I have a class B
that takes a template argument such as A
. I create a B b
and call B::operator()(A a)
. Regardless of the type of a
, b(a)
should return a double. I would like to deduce this from outside of B
using decltype
.
If I had a function B::operator()()
, I could do that with
std::declval<B&>()()
This was presented to me in my other question here. (Note, A
and B
in this question do not match A
and B
in the previous question.)
If I had a function B::operator()(int i)
(no template), I could do that with
std::declval<B>()(int())
although this appears to only work because int
is default constructible.
How do I do it when B::operator()()
is a template function?
Below is some starting code that compiles on my machine. You shouldn't need to look at it to understand the question.
#include <array>
#include <iostream>
#include <array>
class B {
public:
B() {};
template<typename T>
double operator()(T t) {
return t();
}
};
class A {
public:
A() {};
double operator()() {
return 3;
}
};
int main() {
A a{};
B b{};
std::cout << b(a);
return 0;
}
Edit:
To clarify, I want to add a line like
using custom_typename = double;
to the above code, except, instead of double
, I write something like
using custom_typename = decltype(std::declval<B>()());
modified appropriately to take the return type of B::operator()(T t)
instead of B::operator()()
.
I believe you're looking for
decltype(std::declval<B>()(std::declval<A>())) c = b(a);
Broken down:
std::declval<B>() //pretend there's a B object
std::declval<A>() //pretend there's an A object
std::declval<B>()(std::declval<A>()) //call b(a) with these
decltype(std::declval<B>()(std::declval<A>())) //tell me the return type
Or, if you wanted to hide that verbosity:
template<typename T>
using B_return_t = decltype(std::declval<B>()(std::declval<T>()));
B_return_t<A> c = b(a);
http://coliru.stacked-crooked.com/a/4e6e235b47b12cdd
I assume this doesn't count:
auto c = b(a);