The compiler is right, it refers to types, not values. You need to write:
operator decltype(std::declval<T>()(std::declval<U>()...))() const {
// you need ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ and ^^
return a(b...);
}
(the last ()
are needed to make it a valid conversion operator of the form operator T() const
)
That said, you can not use a
and b...
inside of Inner
, so the whole example doesn't make any sense. Whatever your use-case is, the above doesn't really work, I can just show you how to fix the signature so that Clang accepts the code, but you will still be unable to use it.
And after your update, it's an entirely different question now. Maybe this works for you:
template <typename R>
class A {
R value = R();
public:
A() { }
~A() { }
template <typename T, typename... U>
A& operator ()(T a, U... b)
{
struct Inner {
using R2 = decltype(std::declval<T>()(std::declval<U>()...));
R2 impl(T a, U... b) const {
return a(b...);
}
} inner;
value += inner.impl(a,b...);
return *this;
}
R val() {
return value;
}
};
Referring to Walter's comment: You could, now that you pass the parameters, also use trailing return types:
struct Inner {
auto impl(T a, U... b) const -> decltype(a(b...)) {
return a(b...);
}
} inner;
or with C++14, you could use
struct Inner {
auto impl(T a, U... b) const {
return a(b...);
}
} inner;