如何启动会使最后一个注释行编译的内容?我如何更改此代码以使其工作?
#include<iostream>
using namespace std;
template <int x>
class someclass{
public:
int size;
int intarr[x];
someclass():size(x){}
};
template<int x, int y>
int somefunc(someclass<x> A, someclass<y> B){
return ( A.size > B.size ? A.size : B.size);
}
template<int x, int y, int z>
someclass<x> anotherfunc(someclass<y> A, someclass<z> B){
return ( A.size > B.size ? A : B);
}
int main(){
someclass<5> A;
someclass<10> B;
cout << "SIZE = " << somefunc(A,B) << endl;
//cout << "SIZE = " << (anotherfunc(A,B)).size << endl; //THIS DOES NOT COMPILE
return 0;
}
答案 0 :(得分:4)
如何知道函数外部x
是什么? (它无法查看正文,因为在中它看起来功能的主体取决于x
得到的值!)。此外,你不能写?:
,因为你的两个分支都产生完全不相关的类型,这些类型不可能达到一个普通类型。但是该运算符需要为它所评估的两个分支都有一个公共类型。
然后另一个帖子已经详细阐述了size
不是编译时常量的另一个问题。
我认为这应该有效:
template<int y, int z>
someclass<sizeof (char[+(y >= z)]) * y> anotherfunc(someclass<y> A, someclass<z> B){
return A;
}
template<int y, int z>
someclass<sizeof (char[+(y < z)]) * z> anotherfunc(someclass<y> A, someclass<z> B){
return B;
}
现在调用它时,参数推导出y
和z
,然后将参数替换为返回类型。 sizeof(char[1 or 0])
将测试y
或z
是否更大。在将其计算为sizeof(char[1])
(产生1)的相应模板中,我们将乘以更大(或相等)的值。如果相应的模板产生sizeof(char[0])
,则这是一个演绎失败(数组不能为零大小!),并且模板不会通过重载决策选择(称为 SFINAE ) 。
一元+
将1
或0
作为int而不是true
或false
,这可能会导致某些编译器出现编译器警告。
enable_if
还有“干净”的方式。它没有做一些可怕的sizeof
技巧,而是使用一般建立的enable_if模式。 Boost有一个实现它
template<int y, int z>
typename boost::enable_if_c<(y >= z), someclass<y> >::type
anotherfunc(someclass<y> A, someclass<z> B){
return A;
}
template<int y, int z>
typename boost::enable_if_c<(y < z), someclass<z> >::type
anotherfunc(someclass<y> A, someclass<z> B){
return B;
}
这可能乍一看看起来更嘈杂,但应该更容易理解,并且更快地跟随已经习惯enable_if
的人(boost的实现的_c
变体接受普通的布尔值,如上文)。
答案 1 :(得分:3)
请记住,在C ++中,一切都是在编译时确定的。在anotherfunc
中,直到运行时才知道是否返回“y-typed”或“z-typed”类。如果要从函数返回模板类,则需要知道要返回的内容。
你可以通过重载中间类的强制转换操作符来获取一些技巧,以获得看起来像在返回类型上重载的东西,但这实际上是在滥用语言(并且你仍然需要在编译时知道返回类型!)