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?