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

Why can't I create a temporary of this templated class with an lvalue constructor argument?

对于我来说,我似乎无法临时创建此 class,为什么它不允许我这样做?

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 模板参数的初始化器。另一个错误是你不能在声明符周围加上括号 class 模板参数推导。

Dog<int>(tag); 类似,它是 Dog<int> 类型变量 tag 的声明符。由于参数是显式的,因此不需要进行推导,但这里的错误是您没有 Dog 的默认构造函数,并且您自己没有为构造函数提供参数。

Dog{tag}; 没有与括号相同的问题。它声明了一个临时 Dog,如您所料,用 tag 构造。

由于 C++ 解析规则,

Dog<int>(tag);

相当于

Dog<int> tag;

引入大括号初始化是为了避免这些解析歧义:

Dog<int>{tag};