At what point is a variation pattern considered "declared"? This compiles under clang ++ 3.4, but not under g ++ 4.8.2.
template <typename T>
const T &sum(const T &v) { return v; }
template <typename T, typename ... Ts>
auto sum(const T &v, const Ts & ... params) -> decltype(v + sum(params...));
template <typename T, typename ... Ts>
auto sum(const T &v, const Ts & ... params) -> decltype(v + sum(params...)) {
return v + sum(params...);
}
int main() {
sum(1, 2, 3);
}
Apparently g ++ will not match the function itself in the return type. Error from g ++ 4.8.2:
sum.cpp: In function 'int main()':
sum.cpp:13:16: error: no matching function for call to 'sum(int, int, int)'
sum(1, 2, 3);
^
sum.cpp:13:16: note: candidates are:
sum.cpp:2:10: note: template<class T> const T& sum(const T&)
const T &sum(const T &v) { return v; }
^
sum.cpp:2:10: note: template argument deduction/substitution failed:
sum.cpp:13:16: note: candidate expects 1 argument, 3 provided
sum(1, 2, 3);
^
sum.cpp:8:6: note: template<class T, class ... Ts> decltype ((v + sum(sum::params ...))) sum(const T&, const Ts& ...)
auto sum(const T &v, const Ts & ... params) -> decltype(v + sum(params...)) {
^
sum.cpp:8:6: note: template argument deduction/substitution failed:
sum.cpp: In substitution of 'template<class T, class ... Ts> decltype ((v + sum(sum::params ...))) sum(const T&, const Ts& ...) [with T = int; Ts = {int, int}]':
sum.cpp:13:16: required from here
sum.cpp:5:74: error: no matching function for call to 'sum(const int&, const int&)'
auto sum(const T &v, const Ts & ... params) -> decltype(v + sum(params...));
^
sum.cpp:5:74: note: candidate is:
sum.cpp:2:10: note: template<class T> const T& sum(const T&)
const T &sum(const T &v) { return v; }
^
sum.cpp:2:10: note: template argument deduction/substitution failed:
sum.cpp:5:74: note: candidate expects 1 argument, 2 provided
auto sum(const T &v, const Ts & ... params) -> decltype(v + sum(params...));
^
Addendum: If I remove the declaration of the variational template, both clang ++ and g ++ give errors.
Addedum 2: I see that a similar question was asked earlier. I think the real question is why it works with one compiler and not another. In addition, I can get it to work with g ++, forcing ADLs in POI to use non-primitive sum () arguments.
Addendum 3: This works with both clang ++ and g ++:
class A {
};
A operator+(const A &, const A &) {
return A();
}
template <typename T>
const T &sum(const T &v) { return v; }
template <typename T, typename ... Ts>
auto sum(const T &v, const Ts & ... params) -> decltype(v + sum(params...)) {
return v + sum(params...);
}
int main() {
sum(A(), A(), A());
}