为什么我不能使用左值构造函数参数创建此模板化类的临时值?



就我而言,我似乎无法创建此类的临时对象,为什么它不允许我创建?

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 xint (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};

最新更新