C++11 解决方案可以基于 SFINAE:如果 U 是基于 S 的类型,则启用第一个或第二个构造函数。
为了做到这一点,开发一个类型特征来检测一个类型是否(或不是)S 是有用的;举例
template <typename>
struct isS : public std::false_type
{ };
template <typename T>
struct isS<S<T>> : public std::true_type
{ };
使用isS,您可以如下编写构造函数(在A 类的主体中)
template <typename V = U>
A(T & t, bool b,
typename std::enable_if<false == isS<V>::value>::type * = nullptr )
: U(t, b)
{ std::cout << "generic A constructor" << std::endl; }
template <typename V = U>
A(T & t, bool b,
typename std::enable_if<true == isS<V>::value>::type * = nullptr)
: U(t, b, false)
{ std::cout << "S specific A constructor" << std::endl; }
如果需要S的模板参数,可以定义isS的特化如下
template <typename T>
struct isS<S<T>> : public std::true_type
{ using type = T; };
并将其用作typename isS<V>::type。
一个完整的工作示例
#include <vector>
#include <iostream>
#include <type_traits>
template <typename T>
struct S
{
S (T const &, bool, bool)
{ std::cout << "S constructor" << std::endl; }
};
template <typename>
struct isS : public std::false_type
{ };
template <typename T>
struct isS<S<T>> : public std::true_type
{ };
template <typename T, typename U>
struct A : public U
{
template <typename V = U>
A(T & t, bool b,
typename std::enable_if<false == isS<V>::value>::type * = nullptr )
: U(t, b)
{ std::cout << "generic A constructor" << std::endl; }
template <typename V = U>
A(T & t, bool b,
typename std::enable_if<true == isS<V>::value>::type * = nullptr)
: U(t, b, false)
{ std::cout << "S specific A constructor" << std::endl; }
};
int main ()
{
long l { 0L };
// print "generic A constructor"
A<long, std::vector<int>> alv(l, true);
// print "S constructor>" and "S specific A constructor"
A<long, S<int>> als(l, true);
}