可变模板和复制构造函数

Variadic template and copy constructors

本文关键字:复制 构造函数      更新时间:2023-10-16

为什么下面的代码不能编译:

struct a
{
    int i;
};

template <typename T>
class b
{
public:
    T mItem;

    template <typename... Arguments>
    b(Arguments&&... args) : mItem(std::forward<Arguments>(args)...)
    {
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    b<a>(1);
    return 0;
}

错误C2664: 'a::a(const a &)':无法从'int'转换参数1To 'const a &'

但是只要像这样添加一个额外的参数,它就可以编译:

struct a
{
    int i;
};

template <typename T>
class b
{
public:
    T mItem;

    template <typename... Arguments>
    // just random extra argument
    b(int, Arguments&&... args) : mItem(std::forward<Arguments>(args)...)
    {
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    b<a>(1);
    return 0;
}

是否有比简单地向b的构造函数添加额外(无用的)参数更干净的方法?

您正在尝试依赖聚合初始化,但是您需要使用大括号而不是括号来使用它:

template <typename... Arguments>
b(Arguments&&... args) : mItem{std::forward<Arguments>(args)...}
{
}

大括号表示使用的是列表初始化,而不是value-/直接初始化。当T为聚合类型时,前者解析为聚合初始化,后两者则不解析。是啊,c++的初始化规则很奇怪

在第一种情况下,您尝试调用

a(1)

你没有。

在第二种情况下,您的1参数被int消耗,其余参数(即无)进入args。因此,调用

a()

请注意,在后一种情况下,传递给b<a>::b1的值丢失了,并且没有像您可能期望的那样转发给a::i

您正在尝试用int初始化A。A对int一无所知,在A中没有构造函数可以做到这一点。当您提供一个额外的int参数时,您只是丢弃它,然后使用空参数列表初始化A,调用默认构造函数。