就我而言,我似乎无法创建此类的临时对象,为什么它不允许我创建?
template <typename T>
struct Dog
{
Dog(T t) : tag(t) {}
T tag;
};
int main()
{
int tag = 6;
Dog<int>(6); // Works fine
Dog<int>(tag); // On Visual Studio I get no default constructor exists for class Dog<int>
// On onlineGDB I get error: no matching function for call to ‘Dog::Dog()’
}
另外,这里的区别是什么,再次在右值和左值之间:
Dog(6); // Deduces fine
Dog(tag); // Deduction fail, error: missing template arguments before ‘(’ token
还有:
Dog<int>{tag}; // Works.
我接受它是因为这是聚合初始化?
Dog(6);
和Dog<int>(6);
声明临时Dog<int>
s,用值6构造。模板参数推导在第一种情况下效果良好,而模板参数在第二种情况下是显式的。
但是,Dog(tag);
是而不是创建临时的。它是Dog<?>
类型的变量tag
的声明符。通常,括号是多余的,即。int x
、int (x)
、int ((x))
都是等价的。在这种情况下,错误在于您没有给出用于推导Dog
的模板参数的初始值设定项。另一个错误是,在进行类模板参数推导时,不能在声明符周围使用括号。
Dog<int>(tag);
类似,它是Dog<int>
类型的变量tag
的声明符。由于参数是显式的,因此不需要进行推导,但这里的错误是您没有Dog
的默认构造函数,而且您自己也没有为构造函数提供参数。
Dog{tag};
与使用括号的问题不同。它声明了一个用tag
构建的临时Dog
,正如您所期望的那样。
由于C++解析规则,
Dog<int>(tag);
相当于
Dog<int> tag;
引入Brace初始化是为了避免这些解析歧义:
Dog<int>{tag};