参数包扩展失败

时间:2014-04-28 17:19:11

标签: visual-studio templates c++11 variadic-templates

考虑以下简化的C ++代码:

template <typename ... TEventArgs>
struct Event
{
    // ...
};

template <typename T>
struct Parameter
{
    using Type = T;
    // ...
};

template <typename ... Parameters>
struct Command
{
    Event<typename Parameters::Type...> Invoked;
};

int main()
{
    Command<Parameter<int>, Parameter<float>> c;
}

Visual Studio C ++编译器(2013年11月CTP,Visual Studio 2013 Update 1)产生以下错误: source.cpp(17):错误C3546:&#39; ...&#39; :没有可用于扩展的参数包

Mingw 4.8.1。另一方面编译代码没有任何问题。显然,Visual Studio编译器有一个错误,当表达式涉及访问一种可变参数时,它会阻止它扩展参数包。但是,其他扩展工作。例如,Event<std::vector<Parameters>...> Invoked;成功编译,或者你甚至可以成功访问静态成员,在Command的构造函数SomeVariadicFunc(Parameters::SomeStaticFunc()...);中调用这样的可变参数函数。

所以,问题是:

1)哪个编译器出错:Visual Studio还是mingw?虽然我没有看到任何阻止typename Parameters::Type参数包扩展工作的内容,但我并不是100%确定它是有效的C ++。

2)有解决方法吗?基本上,我必须从&#34;序列&#34;执行投射。 Parameters到&#34;序列&#34; Parameters::Type。那可能吗?我尝试使用递归结构构造该列表,但我只能提出类似myStruct<type1, mystruct<type2, mystruct<type3, ...>>>的内容,这不是我需要的内容。

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

Yakk能够在上面的评论中提出解决问题的方法。与Visual Studio和mingw完美编译的最终版本如下:

template <typename ... TEventArgs>
struct Event
{
    // ...
};

template <typename T>
struct Parameter
{
    using Type = T;
    // ...
};

template <typename ... Parameters>
struct Command
{
private:
    // Workaround for the Visual Studio bug
    template<typename T> struct ExpandArgs
    {
        typedef typename T::Type Type;
    };

public:
    Event<typename ExpandArgs<Parameters>::Type...> Invoked;
};

int main()
{
    Command<Parameter<int>, Parameter<float>> c;
}