标准库的std::common_reference<> https://cppreference.fasanowood.com/en/cpp/types/common_reference.html非常接近您想要的,并且可以说是您想要的foo()
应该使用函数,因为它清楚地表达了所需的语义:
template<typename T1, typename T2>
std::common_reference_t<const T1&, const T2&> foo(const T1& a1, const T2& a2) {
if(a1 < a2) return a1;
return a2;
}
不幸的是,对于这个特定的用例,它不能开箱即用,因为它无法检测公共基础,除非其中一种类型派生于另一种类型。
但是,您可以通过专门化来给出提示std::common_type https://en.cppreference.com/w/cpp/types/common_type。就像这样:
namespace std {
template<>
struct common_type<MyString1, MyString2> {
using type = std::string;
};
}
它会“正常工作”。您可以在这里看到它的实际效果:https://gcc.godbolt.org/z/e3PrecPac https://gcc.godbolt.org/z/e3PrecPac.
Edit:值得一提的是,根据您的情况,您还可以创建通用的专业化std::common_type
对于从给定基派生的所有类型:
struct SomeBase {};
namespace std {
template<std::derived_from<SomeBase> T1, std::derived_from<SomeBase> T2>
struct common_type<T1, T2> {
using type = SomeBase;
};
}
不过,我会对此略加讨论。这是一个潜在的非常广泛和广泛的部分专业化。它很容易导致歧义,特别是如果多次这样做的话。