I have a function definition like so
template <typename T>
auto print(T t) -> decltype(t.print()) {
return t.print();
}
The idea is that the argument must be of type T
and must have the print
function. This print
function could return anything, explaining the need of decltype
. So for example you can do:
struct Foo
{
int print()
{
return 42;
}
};
struct Bar
{
std::string print()
{
return "The answer...";
}
};
...
std::cout << print(Foo()) << std::endl;
std::cout << print(Bar()) << std::endl;
/* outputs:
42
The answer...
*/
I read that templates cannot do runtime instantiation and that you can have the classes derive from a base class, then determine their types to see what template argument to use. However, how would I do this for a non-class
type? The idea is to be able to have:
template <typename T>
T print(T t) {
return t;
}
as well, but this gives me ambiguous overload errors. Qualifying doesn't work, ie print<Foo>
. And the other got'cha is, what if I had a functor like:
struct Foo
{
virtual int print();
operator int() const
{
return 42;
}
};
How does it decide now?
So my question is, is it possible to resolve all these ambiguities with templates, or do I have to write a bunch of redundant code?
Tests
I incrementally added tests, copy/pasting each edit'ed solution from below. Here are the results:
With the following classes:
struct Foo
{
int print()
{
return 42;
}
operator int() const
{
return 32;
}
};
struct Bar
{
std::string print()
{
return "The answer...";
}
operator int() const
{
return (int)Foo();
}
};
struct Baz
{
operator std::string() const
{
return std::string("The answer...");
}
};
And the following test output:
std::cout << print(Foo()) << std::endl;
std::cout << print(Bar()) << std::endl;
std::cout << print(42) << std::endl;
std::cout << print((int)Foo()) << std::endl;
std::cout << print("The answer...") << std::endl;
std::cout << print(std::string("The answer...")) << std::endl;
std::cout << print((int)Bar()) << std::endl;
std::cout << print((std::string)Baz()) << std::endl;
Both correctly output:
42
The answer...
42
32
The answer...
The answer...
32
The answer...