0

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

但问题仍然是为什么?

4

2 回答 2

3

您习惯于看到如下代码:

T(arg1, arg2)

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

f(T(arg1, arg2))

你也看到了它的一个论点:

f(T(arg1))

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

那是:

T(arg1);

是相同的:

T arg1;

如果一段代码可能是声明表达式,它始终是声明。这本质上是一个最令人头疼的解析示例。

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

(T(arg1));

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

于 2013-02-17T13:30:43.903 回答
1

你想定义一个对象,不是吗?

那么,Tokenize<std::function<bool (wchar_t)> >(foo);应该是Tokenize<std::function<bool (wchar_t)> > tokenizer(foo);

于 2013-02-17T13:18:42.827 回答