代码之家  ›  专栏  ›  技术社区  ›  Zebrafish

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

  •  2
  • Zebrafish  · 技术社区  · 4 年前

    就我的一生而言,我似乎不能创造一个暂时的这个类,为什么它不允许我呢?

    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. 
    

    因为这是聚合初始化?

    2 回复  |  直到 4 年前
        1
  •  4
  •   cigien Jorge Eldis    4 年前

    Dog(6); Dog<int>(6); Dog<int> s、 用值6构造。在第一种情况下,模板参数推导工作正常,在第二种情况下,模板参数是显式的。

    Dog(tag); 创建临时文件夹。它是一个变量的声明符 tag 类型 Dog<?> int x , int (x) , int ((x)) 都是等价的。在本例中,错误是您没有给出一个初始值设定项,用它来推断的模板参数 Dog . 另一个错误是,在进行类模板参数推导的声明符周围不能有括号。

    Dog<int>(tag); 类似的,它是一个变量的声明符 标签 类型 狗<内部> . 因为参数是显式的,所以不需要进行任何推导,但是这里的错误是您没有默认的构造函数 ,并且您自己还没有为构造函数提供参数。

    Dog{tag}; 与括号的问题不同。它声明了一个临时的 构造 如你所料。

        2
  •  4
  •   zdan    4 年前

    Dog<int>(tag);
    

    相当于

    Dog<int> tag;
    

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

    Dog<int>{tag};