这里是一个可能的解决方案(因为C++ 11的工作 - 好,它的工作原理与C++ 14,但它与C++ 11做的,如果你使用Base<T>
,而不是auto
作为返回类型为f
) :
#include<utility>
#include<type_traits>
template<class T>
class Base{ };
template<class T>
class OtherRandomClass{ };
template<class T, class Other>
class Derived :
public virtual Base<T>,
public virtual OtherRandomClass<Other>
{ };
template<typename T>
constexpr auto f(const Base<T> &b) { return b; }
template<typename T>
struct S {
using type = decltype(f(std::declval<T>()));
};
int main() {
static_assert(std::is_same<typename S<Derived<int, double>>::type, Base<int>>::value, "!");
}
如果Derived
继承比Base
一次它不工作。
使用sfinae(类似于void_t
成语),甚至可以设计一个类似于enable_if
的类:它只有在T
实际上从Base
继承一次时才具有type
。
这将有以下形式:
template<typename T>
constexpr auto f(const Base<T> &b) { return b; }
template<typename...>
using void_t = void;
template<typename T, typename = void_t<>>
struct S { };
template<typename T>
struct S<T, void_t<decltype(f(std::declval<T>()))>> {
using type = decltype(f(std::declval<T>()));
};
这个结构可以在编译时对任何模板欺骗你能想象的使用。
在这两种情况下,S::type
(如果存在)是Derived
继承的基类的类型,即Base<T>
。
有关详细信息,请参见main
函数中的static_assert
。
你可以简单地在Derived中提供一个'typedef'。 –
@ Cheersandhth.-Alf这是真实的....但我懒惰,不想重写一吨代码(所有想法可能是我倒退) – DarthRubik
另一种方法是编译所有可能的' T'类型。更多的工作。 –