c++ - 尝试使用 std::function 实例化模板时出现错误 C2371

标签 c++ templates visual-c++ c++11

考虑以下 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;
}

尝试使用 VC++ 进行编译时,因编译器错误而失败

error C2371: 'foo' : redefinition; different basic types
error C2512: 'Tokenize<Ty>' : no appropriate default constructor available

看起来它试图重新定义 foo,但不知道究竟如何

注意 仔细检查会发现编译器认为

Tokenize<std::function<bool (wchar_t)> >(foo)

构造一个 Tokenize<std::function<bool (wchar_t)> > 类型的对象使用默认参数,即

Tokenize<std::function<bool (wchar_t)> >  foo

但问题仍然是为什么?

最佳答案

你习惯于看到这样的代码:

T(arg1, arg2)

为了创建 临时 T 类型。您习惯于在表达式中看到这一点,例如:

f(T(arg1, arg2))

你也见过它有一个参数:

f(T(arg1))

但是,当您假定的临时创建是一行代码中的完整 语句时,它在句法上与声明没有区别。

即:

T(arg1);

等同于:

T arg1;

如果一段代码可能是一个声明一个表达式,它始终是一个声明。这本质上是 most vexing parse 的一个示例.

您可以使用 () 来消除歧义,强制将语句读作表达式:

(T(arg1));

但我通常会问,为什么您觉得有必要在自己的行上创建一个临时的,然后您什么都不做。

关于c++ - 尝试使用 std::function 实例化模板时出现错误 C2371,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14921474/

相关文章:

c++ - 在没有 std::merge 的情况下合并两个 STL 容器

c++ - 为 Turtle 中的常量方法创建 Mock

templates - 我怎样才能得到dag中的execution_date?运算符的外部?

来自 C++ 定义变量的 C++ Gnuplot 管道输入

c# - 您会使用哪种 C# 项目类型重新开发 MFC C++ activex 控件?

c++ - 根据参数包值定义模板

c++ - 可变参数模板函数的部分特化

c++ - 加载接口(interface)失败

c++11 - vs 2015 pro 上没有 C++11?

c++ - "cannot access private member' "只有当类有导出链接时才会出错