3

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?

10
  • How do you call your compiler? Commented May 13, 2014 at 8:17
  • I believe that static inline auto fill(T self, Arg0 value, Args... values) -> decltype(fill(self.add(value), values...)) could not compile, because it is a recursive declaration. The return type of the function can not be the decltype of the return type of the function itself. Commented May 13, 2014 at 8:22
  • see full code here coliru.stacked-crooked.com/a/bbacd7e9bec149f0 Commented May 13, 2014 at 8:36
  • @Klaus - really? Where you read that? Commented May 13, 2014 at 8:36
  • @BЈовић - Oh, indeed, that crush whole thing. Commented May 13, 2014 at 8:37

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I thought about it too, as I describe in question open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1433 . But ... why "fill" works ok than? It has the same variadic params...
sorry I missed that in your Q (browser didn't refresh). OTOH, Clang does compile your code on Coliru (if you disable the warning on the unused list variable).
Yep it compiles, so I made a bug on gcc bugzilla gcc.gnu.org/bugzilla/show_bug.cgi?id=61178, just to be sure :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.