Return type deduction substitution failure on clang, but not on g++

Viewed 195

The following snippet does not compile with clang, but with g++ (details below):

#include <utility>

struct S {
    template<typename T>
    void operator()(T&& /*t*/) {}

    template<typename T0, typename T1, typename... Args>
    auto operator()(T0&& t0, T1&& /*t1*/, Args&&... args) ->
        decltype(operator()(std::forward<T0>(t0), std::forward<Args>(args)...))
    {}
};

int main(int /*argc*/, char** /*argv[]*/) {
    S()(1, 2);
    S()(1, 1.2, 1.2); // does not compile with clang
}

I.e. the variadic operator() should recurse until it reaches the base case.

When I compile this with gcc 7.2.0 (g++ -std=c++1y), it compiles. But with clang 3.8.0 (clang++ -std=c++1y), I obtain the following compilation failure:

main.cpp:15:5: error: no matching function for call to object of type 'S'
    S()(1, 1.2, 1.2); // does not compile with clang
    ^~~
main.cpp:8:10: note: candidate template ignored: substitution failure [with T0 = int, T1 = double, Args = <double>]: no matching member function for call to 'operator()'
    auto operator()(T0&& t0, T1&& /*t1*/, Args&&... args) ->
         ^
main.cpp:5:7: note: candidate function template not viable: requires 1 argument, but 3 were provided
        void operator()(T&& /*t*/) {}

Is this a bug in one of the compilers or am I possibly hitting undefined behaviour somewhere?

0 Answers
Related