为什么不能将std::cout
的地址作为模板参数传递?
或者如果有可能那么如何?
以下是我的尝试:
#include <iostream>
template<std::ostream* stream>
class MyClass
{
public:
void disp(void)
{ (*stream) << "hello"; }
};
int main(void)
{
MyClass<&(std::cout)> MyObj;
MyObj.disp();
return 0;
}
我从clang++ -std=c++11
得到的错误消息:
main.cpp:15:11: error: non-type template argument does not refer to any declaration
MyClass<&(std::cout)> MyObj;
^~~~~~~~~~~
main.cpp:6:24: note: template parameter is declared here
template<std::ostream* stream>
^
1 error generated.
和g++ -std=c++11
:
main.cpp: In function ‘int main()’:
main.cpp:15:22: error: template argument 1 is invalid
MyClass<&(std::cout)> MyObj;
^
main.cpp:15:29: error: invalid type in declaration before ‘;’ token
MyClass<&(std::cout)> MyObj;
^
main.cpp:16:8: error: request for member ‘disp’ in ‘MyObj’, which is of non-class type ‘int’
MyObj.disp();
^
有什么想法吗?
答案 0 :(得分:5)
在C ++ 17删除此限制之前,指针或参考模板参数的模板参数的语法形式受到限制。 N4140 [temp.arg.nontype] /1.3表示必须
表示(忽略括号)为
&
id-expression ,其中 id-expression 是对象或函数的名称,除了 如果名称引用函数或数组,则&
可以省略 如果相应的模板参数是a,则应省略 参考
(std::cout)
不是 id-expression 。这是 primary-expression 。
Core issue 773添加了“(忽略括号)”部分,显然是为了允许(&i)
,而不是&(i)
。
答案 1 :(得分:2)
这会修复你的代码,省略括号:
#include <iostream>
template<std::ostream* stream>
class MyClass
{
public:
void disp(void) {
(*stream) << "hello";
}
};
int main(void)
{
MyClass<&std::cout> MyObj;
MyObj.disp();
return 0;
}
更详细的解释为什么可以在这里找到: