I have a problem where I'd like to provide a generic version of a function foo
which may only be applied when there is absolutely no other match for an invocation. How can I modify the following code such that last_resort::foo
is a worse match for derived::type
than base::foo
? I'd like to find a solution which does not involve modifying the definition of bar
and which would preserve the type of the argument of last_resort::foo
.
#include <iostream>
namespace last_resort
{
template<typename T> void foo(T)
{
std::cout << "last_resort::foo" << std::endl;
}
}
template<typename T> void bar(T)
{
using last_resort::foo;
foo(T());
}
namespace unrelated
{
struct type {};
}
namespace base
{
struct type {};
void foo(type)
{
std::cout << "base::foo" << std::endl;
}
}
namespace derived
{
struct type : base::type {};
}
int main()
{
bar(unrelated::type()); // calls last_resort::foo
bar(base::type()); // calls base::foo
bar(derived::type()); // should call base::foo, but calls last_resort::foo instead
return 0;
}
Defining a Function TemplateA function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
Which one is suitable syntax for function template? Explanation: Both class and typename keywords can be used alternatively for specifying a generic type in a template.
A code for template function is generated when the function is instantiated. The functions are often instantiated when they are first time called (in the code), but there are other ways to instantiate a function - do a so-called 'explicit instantiation'.
In the C++ programming language, argument-dependent lookup (ADL), or argument-dependent name lookup, applies to the lookup of an unqualified function name depending on the types of the arguments given to the function call.
This would be about as bad as it gets:
struct badParam { template <typename T> badParam(T t) { } };
namespace last_resort {
void foo(badParam, int dummy = 0, ...) {
std::cout << "last_resort::foo" << std::endl;
}
}
You've got a user-defined conversion, a defaulted parameter and an unused ellipsis.
[edit]
Slight variant, to save T
I moved the user-defined conversion to the dummy parameter:
struct badParam {
badParam() { }
operator int() { return 42; }
};
namespace last_resort {
template <typename T> void foo(T t, int dummy = badParam(), ...) {
std::cout << "last_resort::foo" << std::endl;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With