为什么使用可变参数模板参数初始化我的对象需要定义移动构造函数?

时间:2015-10-28 08:19:19

标签: templates c++11 g++ clang variadic-templates

我想在模板函数中创建一些typename Type的本地对象:

template <typename Type, typename... Args>
void create_local(Args... args)
{
    Type val(args...);
}

现在,当我调用此函数时没有参数(其中Type是一个具有不可复制成员的类):

struct T {
    std::mutex m;
};

int main()
{
    T t;               // OK: No use of move constructor
    create_local<T>(); // Error: Requires deleted move constructor!!!
}

(coliru link)

g ++(从4.7.3到5.2)无法编译,需要定义T的移动构造函数? clang 3.7成功编译。

此外,如果我(1)从T中删除std::mutex成员,(2)声明T的默认构造函数,(3)为T声明一个已删除的复制构造函数:

struct T {
    T() = default;
    T(const T&) = delete;
};

int main()
{
    T t;               // OK: No use of move constructor
    create_local<T>(); // OK: No use of move constructor
}

所有版本的g ++和clang编译成功。为什么g ++不能为任何具有不可复制成员的类型Type编译?

1 个答案:

答案 0 :(得分:1)

根据Andrey Zholos在this错误报告中的评论:

  

我也偶然发现了这个错误,而错误59141是重复的。

     

空参数包似乎扩展为t({})而不是t()。

     

14.5.3p6中有一个类似的例子,表明obj应该是值初始化的(不是复制构造的),clang接受这个代码。