带模板化函数的C ++ 11奇怪错误

时间:2014-05-13 08:14:29

标签: c++ templates c++11 variadic-templates variadic-functions

我有以下代码:

#include <iostream>
#include <utility>
#include <type_traits>
#include <typeinfo>

using namespace std;


struct Void{
    static constexpr int size = 0;
};

template<typename T0, typename T1>
class Variadic{
private:
    typedef Variadic<T0, T1> thisT;

public:
    /** Do not use this constructor */
    Variadic(T0 el0, T1 el1): value(el0), next(el1) {}

    // avoiding decltype
    typedef T0 valueT;
    T0 value;

    typedef T1 nextT;
    T1 next; // may be next pair

    /**
     * Chainable method
     */
    template<typename ValueT>
    /*constexpr*/ inline Variadic<ValueT, thisT> add(ValueT value){
        return Variadic<ValueT, thisT>(value, (*this) );
    }

};

template<typename T>
/*constexpr*/ static inline Variadic<T, Void> make_variadic(T value){
    return Variadic<T, Void>(value, Void());
}



template<typename Arg0, typename... Args>
static inline auto make_variadic(Arg0 value0, Args... values) -> decltype( fill(make_variadic<Arg0>(value0), values...) ) {
    return fill(make_variadic<Arg0>(value0), values...);
}

/*
template<typename Arg0, typename... Args>
static inline auto make_variadic(Arg0 value0, Args... values) -> decltype(fill(Variadic<Arg0, Void>(value0, Void()), values...)) {
    return fill(Variadic<Arg0, Void>(value0, Void()), values...);
}*/


template<typename T, typename Arg0, typename... Args>
static inline auto fill(T self, Arg0 value, Args... values) -> decltype(fill(self.add(value), values...)){
    return fill(self.add(value), values...);
}

template<typename T, typename Arg0>
static inline auto fill(T self, Arg0 value) -> decltype(self.add(value)){
    return self.add(value);
}



int main()
{
    auto list = make_variadic(1, 2, 3);
}

代码为IS http://coliru.stacked-crooked.com/a/bbacd7e9bec149f0

当我尝试用gcc 4.8编译它时,我得到以下错误:

  

扩展模式&#39;#&#39; nontype_argument_pack&#39; dump_expr#

不支持

这是http://open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1433还是https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51501

或者这是完全不同的东西?

1 个答案:

答案 0 :(得分:1)

在Google上搜索您的错误消息,这看起来与compiler bug相关,该known Defect Report与尾随返回类型相关的缩减为{{3}}:

  

<强> 1433。 trailing-return-type和声明点

     

章节:3.3.2 [basic.scope.pdecl]状态:扩展名
  发布者:Jason Merrill日期:2011-12-20这看起来很像   应该是格式良好的:

template <class T> T list(T x);

template <class H, class ...T>
auto list(H h, T ...args) -> decltype(list(args...));


auto list3 = list(1, 2, 3); 
     

但它不是,因为第二个列表不在其自己的尾随返回类型的范围内;重点   声明是在声明者之后,其中包括   尾随回报型。因为int没有关联的命名空间,所以   在返回类型中调用只能看到第一个列表。 G ++,EDG和Clang   所有人都在此基础上拒绝测试用例。

     

但这似乎是编写可变函数的自然模式   模板,我们可以通过移动声明点来支持它   到 - &gt;。这意味着必须只处理一个函数   有一个返回类型的占位符,但我认为我们可以处理它。

     

理由(2012年2月):

     

这是对语言扩展的请求,因此更多   EWG妥善解决。