I am almost certain that what I'm looking for cannot be done without reflection, which is not yet in the language. But occasionally I'm getting surprised with exceptional answers in SO, so let's try.
Is it possible to deduce the "common_base" of two types that have a common shared base class, so the following would be possible (pseudo code! -- there is no common_base_t
in the language, this is the magic I'm trying to achieve):
template<typename T1, typename T2>
const common_base_t<T1, T2>& foo(const T1& a1, const T2& a2) {
if(a1 < a2) return a1;
return a2;
}
Note that a1
and a2
above do not share a common_type
, just by being siblings (sharing the same base) thus we cannot use the ternary operator.
Note also that changing the above return type to const auto&
doesn't do the trick (it would not compile: inconsistent deduction for auto return type).
Here is a the naïve implementation, requiring the caller to state the expected return type:
template<typename R>
const R& foo(const auto& a1, const auto& a2) {
if(a1 < a2) return a1;
return a2;
}
Then we can call it with:
MyString1 s1 = "hello"; // MyString1 derives from std::string
MyString2 s2 = "world"; // MyString2 also derives from std::string
std::cout << foo<std::string>(s1, s2); // ok we return const lvalue ref
// pointing to one of the above objects
There are many reasons for why this probably cannot be achieved without providing the expected return value. But maybe it could be achieved somehow?