尝试使用std::function实例化模板时出错C2371 考虑以下C++程序 #include <cwchar> #include <cwctype> #include <string> #include <functional> template <typename Ty> struct Tokenize { Ty m_delim; Tokenize(Ty& delim):m_delim(delim){} }; int main() { std::function<bool (wchar_t)> foo = iswdigit; //Compiles fine Tokenize<std::string >(std::string("")); //Compiles fine Tokenize<std::function<bool (wchar_t)> >(foo); // Fails return 0; } #包括 #包括 #包括 #包括 模板 结构标记化{ 蒂姆·德里姆; 标记化(Ty&delim):m_delim(delim){} }; int main(){ std::function foo=iswdigit;//编译良好 标记化(std::string(“”);//编译良好 标记化(foo);//失败 返回0; }
尝试使用VC++编译时失败,出现编译器错误尝试使用std::function实例化模板时出错C2371 考虑以下C++程序 #include <cwchar> #include <cwctype> #include <string> #include <functional> template <typename Ty> struct Tokenize { Ty m_delim; Tokenize(Ty& delim):m_delim(delim){} }; int main() { std::function<bool (wchar_t)> foo = iswdigit; //Compiles fine Tokenize<std::string >(std::string("")); //Compiles fine Tokenize<std::function<bool (wchar_t)> >(foo); // Fails return 0; } #包括 #包括 #包括 #包括 模板 结构标记化{ 蒂姆·德里姆; 标记化(Ty&delim):m_delim(delim){} }; int main(){ std::function foo=iswdigit;//编译良好 标记化(std::string(“”);//编译良好 标记化(foo);//失败 返回0; },c++,templates,visual-c++,c++11,C++,Templates,Visual C++,C++11,尝试使用VC++编译时失败,出现编译器错误 error C2371: 'foo' : redefinition; different basic types error C2512: 'Tokenize<Ty>' : no appropriate default constructor available 错误C2371:“foo”:重新定义;不同的基本类型 错误C2512:“标记化”:没有合适的默认构造函数可用 看起来它试图重新定义foo,但不知道到底是怎么回事 注意仔细检查表
error C2371: 'foo' : redefinition; different basic types
error C2512: 'Tokenize<Ty>' : no appropriate default constructor available
错误C2371:“foo”:重新定义;不同的基本类型
错误C2512:“标记化”:没有合适的默认构造函数可用
看起来它试图重新定义foo,但不知道到底是怎么回事
注意仔细检查表明编译器考虑
Tokenize<std::function<bool (wchar_t)> >(foo)
Tokenize(foo)
使用默认参数构造类型为标记化的对象,即
Tokenize<std::function<bool (wchar_t)> > foo
标记化foo
但问题仍然是为什么?你想定义一个对象,不是吗
然后,Tokenize(foo)代码>应该是标记化标记器(foo)代码>您想定义一个对象,是吗
然后,Tokenize(foo)代码>应该是标记化标记器(foo)代码>您习惯于看到这样的代码:
T(arg1, arg2)
以创建类型为T
的临时文件。您习惯于在表达式中看到这一点,例如:
f(T(arg1, arg2))
你也看到了一个论点:
f(T(arg1))
然而,当您假定的临时创建是代码行上的完整语句时,它在语法上与声明是无法区分的
即:
T(arg1);
同:
T arg1;
当一段代码可能是一个声明或表达式时,它总是一个声明。这本质上是一个例子
您可以使用()
消除歧义,强制将语句作为表达式读取:
(T(arg1));
但是我通常会问,为什么您觉得需要在自己的行上创建一个临时行,然后您什么也不做。您习惯于看到这样的代码:
T(arg1, arg2)
以创建类型为T
的临时文件。您习惯于在表达式中看到这一点,例如:
f(T(arg1, arg2))
你也看到了一个论点:
f(T(arg1))
然而,当您假定的临时创建是代码行上的完整语句时,它在语法上与声明是无法区分的
即:
T(arg1);
同:
T arg1;
当一段代码可能是一个声明或表达式时,它总是一个声明。这本质上是一个例子
您可以使用()
消除歧义,强制将语句作为表达式读取:
(T(arg1));
但是我通常会问,为什么您觉得需要在自己的行上创建一个临时对象,而您什么也不做。但是Synatx可以创建一个临时对象?例如标记化(std::string(“”)代码>是完全合法的代码吗?@Abhijit是。但是std::string s(“”);标记化代码>不再是:)。这取决于上下文。但是Synatx可以创建临时对象吗?例如标记化(std::string(“”)代码>是完全合法的代码吗?@Abhijit是。但是std::string s(“”);标记化代码>不再是:)。这取决于上下文。请注意,如果将std::string
作为非常量引用传递给Tokenize
构造函数,则还应收到编译器错误。VC++在此实例中不符合标准。请注意,如果将std::string
作为非常量引用传递给Tokenize
构造函数,则也会出现编译器错误。VC++在这种情况下不符合标准。那不应该是“它总是一个声明”?@enobayram:呃,是的。它应该是……)“但我通常会问,为什么你觉得有必要在自己的线路上创建一个临时线路,然后你什么都不做。”。。因为它是可重新创建的最小失败代码。@Abhijit:但希望它不会在“您试图解决的实际问题”中起作用,因为它是一种设计气味。你不能提出一个关于糟糕代码的实际有用的问题,你不会在现实生活中使用这些问题,而这些问题只存在于为这个问题呈现测试用例的过程中。。那是圆形的!这不应该是“这永远是一个宣言”@enobayram:呃,是的。它应该是……)“但我通常会问,为什么你觉得有必要在自己的线路上创建一个临时线路,然后你什么都不做。”。。因为它是可重新创建的最小失败代码。@Abhijit:但希望它不会在“您试图解决的实际问题”中起作用,因为它是一种设计气味。你不能提出一个关于糟糕代码的实际有用的问题,你不会在现实生活中使用这些问题,而这些问题只存在于为这个问题呈现测试用例的过程中。。那是圆形的!