Chinaunix首页 | 论坛 | 博客
  • 博客访问: 987989
  • 博文数量: 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 );
}

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

网友评论2012-11-23 15:23:57

周星星
我并不想在你身上浪费太多时间,sorry

1)...

2)对于代码风格,我一向比较认真,或许这是唯一的认同点吧

1. 每一种风格的形成都有着接近“绝对”的理由。
  比如 写成
  ... {
  }
  是为了充分利用屏幕空间,在低分辨率的显示器上,这是接近“必须”的,给程序员一个“一目了然”的可能。
  在现在1024*768,甚至之上这一点已经不必要了,所以这种风格在windows下很少有人用。
  比如 写成
  if ( 而不是 if(
  留一个空格是为了lint等工具处理起来更快,快不了多少,但对于过去的低频CPU,或需要大量此类工具处理的代码而言(比如库),它也是接近“必须”的。

网友评论2012-11-23 15:23:42

158197295
1)那个是专门化,而不是使用。
2)我不是觉得很有成就感,并且我也指出了你的代码风格若干问题,为何要回避?
1、为什么在括号和内部表达式之间留空格?  
2、为什么为非声明形参表使用void  
3、为什么使用class而不是typename  
4、使用struct的应该是数据类型。(公用接口使用interface)
3)”黑客行为”你也理解错误,为模板类和模板函数建立直接关联比专门化可读性高。专门性的限制能力并不是必须的。const在建立标准库的抽象层次上是一种需要。非必须跟多余不是一个概念。
4)之所以作补充是因为考虑到个别人怪异的专门化需要可能会这样写。
5)看你不爽。

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

周星星
我一般懒得理你这样的人(“你也配称高手,别开玩笑了。” ---我何时称过高手?称不称高手和所讨论了问题又有什么关系?),人品太差的话,学业难有精进,因为现在的社会一个人再强也有限,只有广泛交流才能“站在巨人的肩膀上”。

另外你所给出的代码在我的C++圈子里是不需要用来特意提出的,因为我的C++圈子中人人都知道这两者功能完全不同,一个是A<T>和B<T>,一个是A<T>和B<U>,如果你觉得这很有成就感的话,祝愿你在幼儿园学前班能大展宏图。

如果你的“补充上面”是发现了自己的幼稚的话,起码能说明你很聪明,虽然狡辩得牵强;如果不是的话,那我也没什么好说的,不少人认为C/C++中的const多余,和你的想法一样,不过他们还比你强一些,没有认为这是“防卫黑客行为的手段”。

网友评论2012-11-23 15:23:14

158197295
补充上面。
当试图调用template bar
传入foo<Type>使得template bar被展开为
bar<Type>
foo<Type>关联友元应为既存在bar<Type>及其他:
template<class T> void bar(foo<T> a)
{
std::cout << foo<char>().a << std::endl;
}
这也是成立的,但是应用极少。
另一方面,友元是为了有效维护安全代码。而不是防卫黑客行为的手段。
所以从可读性来讲,一般策略均是模板类和模板函数建立整体关联。
一直不觉得这是个问题。

网友评论2012-11-23 15:23:07

明白了
明白了,谢谢星星大哥!