Question

I have the following code:

#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);
}

code as IS http://coliru.stacked-crooked.com/a/bbacd7e9bec149f0

And when I try to compile it with gcc 4.8 I get following error:

expansion pattern '#'nontype_argument_pack' not supported by dump_expr#

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

Or this is something completly different?

Was it helpful?

Solution

Googling for your error message, this looks related to a compiler bug that was reduced to a known Defect Report concerning the trailing return type:

1433. trailing-return-type and point of declaration

Section: 3.3.2 [basic.scope.pdecl] Status: extension
Submitter: Jason Merrill Date: 2011-12-20 This seems like it should be well-formed:

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); 

but it isn't, because the second list isn't in scope in its own trailing-return-type; the point of declaration is after the declarator, which includes the trailing-return-type. And since int has no associated namespaces, the call in the return type only sees the first list. G++, EDG and Clang all reject the testcase on this basis.

But this seems like a natural pattern for writing variadic function templates, and we could support it by moving the point of declaration to the ->. This would mean having to deal with a function that only has a placeholder for a return type, but I think we can handle that.

Rationale (February, 2012):

This is a request for an extension to the language and is thus more appropriately addressed by EWG.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top