可变参数模板和通过赋值的复制构造

Posted

技术标签:

【中文标题】可变参数模板和通过赋值的复制构造【英文标题】:Variadic templates and copy construction via assignment 【发布时间】:2011-01-20 16:37:32 【问题描述】:

考虑这个最小的例子:

template <typename T, typename U>
struct foo ;

template <template <typename...> class Bar>
struct converter

     template <typename... Args>
     converter(const Bar<Args...> &);
;

int main()

    converter<foo> c(foo<int,double>()); // This works.
    // converter<foo> c = foo<int,double>(); This fails

GCC 4.5 和 4.6 的注释行都失败,并显示如下消息:

main.cpp:10:2: error: wrong number of template arguments (1, should be 2)
main.cpp:4:8: error: provided for template<class T, class U> struct foo
main.cpp: In function int main():
main.cpp:15:37: error: conversion from foo<int, double> to non-scalar type converter<foo> requested

如果不使用可变参数模板,而是使用特定数量的模板参数(即本例中的 2 个),则不会出现错误。我有点困惑,因为我预计这两行是完全等价的:这是预期的行为吗?

【问题讨论】:

将转换器 c = 转换器(foo());工作吗? 不,正如下面 Johannes 所指出的,我错误地暗示 main() 的第一行实际上初始化了任何东西。您的建议会产生与注释行相同的错误。 【参考方案1】:

是的,这应该可以工作。这是一个 GCC 错误。 GCC 还没有完全支持 C++0x 可变参数模板(公平地说,规范的细节仍在不断变化)。

你所说的“这行得通”实际上是在声明一个函数;它不会初始化一个对象,这是你想要的。

对于您的意图,请参阅描述 template&lt;typename...&gt; class Bar 如何匹配 foo 的 14.3.3p3,以及描述 foo&lt;Args...&gt; 如何匹配 foo&lt;int, double&gt; 的 14.8.2.5p9。

【讨论】:

Doh,我的错……当然,你没有真正初始化任何东西是对的。谢谢指点 :)【参考方案2】:
template <typename T, typename U>
struct foo ;


struct converter

 template <template <typename...> class Bar, class ...Args>
     converter(const Bar<Args...> &)
;

int main()

    converter c1((foo<int,double>())); // This works.
    converter c2 = foo<int,double>();// This works

【讨论】:

谢谢,这确实解决了这个问题......不幸的是,它并不能很容易地转化为我在课堂上想到的实际用法:(

以上是关于可变参数模板和通过赋值的复制构造的主要内容,如果未能解决你的问题,请参考以下文章

如何将构造函数(可变参数)作为模板参数传递?

可变参数模板

编写可变参数模板构造函数

具有模板函数名称的可变参数模板

为啥编译器不能通过逗号运算符扩展可变参数模板的参数?

如何通过使用可变模板参数来专门化元组的类模板?