Point of declaration for variadic template

前端 未结 1 1985
既然无缘
既然无缘 2021-01-13 22:44

At what point is a variadic template considered \"declared\"? This compiles under clang++ 3.4, but not under g++ 4.8.2.

template 
const T &         


        
相关标签:
1条回答
  • 2021-01-13 23:44

    As this question's answer (provided by Praetorian) indicates, the declaration is only complete after the return type, and GCC is correct. I believe clang's behavior is also allowable, but it's not portable. The answer in the link gives a workaround using a traits class, and that will usually do the job, but it's somewhat awkward and can be error prone (since you have to construct the return type in a separate expression which may differ subtlely from the function expression). Another possible workaround involves making your function a static member of a class template (and then adding a free function that forwards to the static template member).

    There is another workaround that you can consider, which is hinted at in your second example which works on both compilers. When you call sum() on A, you are applying a user-defined type as a parameter. This involves argument-dependent-lookup, which causes the template generation to look a second time for overloads of sum() in the namespace of A (which happens to be the global namespace, the same as sum()), and this allows it to find the variadic function template during instantiation.

    Thus, if you can arrange for one of your arguments to always be a user-defined type requiring ADL, you can then rely on the second phase of overload resolution to find the variadic template after it's fully declared. So, perhaps something like this might meet your need:

    namespace sum_impl {
        struct Dummy { };
    
        template <typename T>
        T const &sum_helper(Dummy, T const &v) { return v; }
    
        template <typename T, typename ... Ts>
        auto sum_helper(Dummy d, T const &v, Ts const &...params)
                -> decltype(v + sum_helper(d, params...)) {
            return v + sum_helper(d, params...);
        }
    
        template<typename... P>
        auto sum( P const &...p )
                -> decltype( sum_helper( Dummy{}, p... ) {
            return sum_helper( Dummy{}, p... );
        }
    }
    using sum_impl::sum;
    
    0 讨论(0)
提交回复
热议问题