Chinaunix首页 | 论坛 | 博客
  • 博客访问: 871146
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-23 15:22:01

自己写代码总是按照标准中规中矩,所以有时候很多有趣的问题发现不了。
这次看别人的一段代码,发现一些平时没在意的东西,代码如下:
template struct foo
{
    friend void bar( foo a );
};

template void bar( foo a )
{
}

int main( void )
{
    foo a;
    bar( a );
}

link不通过,这里的 bar( a ) 竟然不能自动由参数类型 foo 推导出函数类型为 void bar( foo )。
原来编译器看到 friend void bar( foo a )  [T==int]这一句,认为 void bar( foo a ) 是一个非模板函数,link时自然说void bar(struct foo)找不到。
写成bar( a ) 当然可以编译通过,但这个template void bar( foo a )可不是struct foo的友元,只是没用到私有函数,所以看不出来。
正确的写法应该是:

template struct foo;
template void bar( foo a );

template struct foo
{
    friend void bar( foo a );
};

template void bar( foo a )
{
}

int main( void )
{
    foo a;
    bar( a );
}

阅读(1430) | 评论(9) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-23 15:22:59

周星星
是不能运行呀。只是因为你没用到bar,所以可以编译通过

template<class T> struct foo
{
friend void bar( T a );

void test( void )
{
bar( 1 );
}
};

template<class T> void bar( T a )
{
}

int main()
{
foo<int> a;
a.test();
}

网友评论2012-11-23 15:22:50

不明白
真是越说越迷惑了啊,大哥:  
T==int 时,void bar( T a ) 就是 void bar( int a ),这显然是个普通函数。像这样的岂不是也不能运行?
template<class T> struct foo
{
    friend void bar( T a );
};

template<class T> void bar( T a )
{
}

网友评论2012-11-23 15:22:43

周星星
当 T==int 时,void bar( foo<T> a ) 就是 void bar( foo<int> a ),这显然是个普通函数。估计你被 foo<int> 迷惑了,对 bar 而言,foo<int>就是一个确切的类型,而非模板。比如
template<class T> foo
{
};
void bar( foo<int> a )
{
}
此时 bar 难道不是一个普通类型?

既然它不是一个模版函数,编译器怎么会去推导?

网友评论2012-11-23 15:22:32

不明白
星星大哥说:“原来编译器看到 friend void bar( foo<T> a )  [T==int]这一句,认为 void bar( foo<int> a ) 是一个非模板函数,link时自然说void bar(struct foo<int>)找不到。”
这句话怎么理解? 为什么看到friend void bar( foo<T> a )  [T==int]这句 会认为 void bar( foo<int> a ) 是一个非模板函数 ?
即使没认出它是个模版函数,编译器也应该尝试其他名字解析途径,如果找到有一个模版函数的定义正好符合void bar( foo<int> a )的话,就应该把bar(a)当成是这个模版函数的一个特化才对啊,不应该说是找不到啊?