用部分实例化的祖先类代替完全实例化的类
Substitute fully instantiated classes with partially instantiated ancestor classes
我希望accepted_dense_vector<??>::value
返回'true'
时,我给模板参数的形式:
C
为uvector
, dynamic_array
, T
为std::is_arithmetic
时, C<T>
。
当T
为std::is_arithmetic
时
std::array<T,S>
。
当accepted_dense_vector<C>::value
为'true'时,container_reference<C>
所有工作正常,但在派生的,完全实例化类A, C, D中,我想删除解决parent
定义。
我该怎么做?
#include <iostream>
#include <array>
using namespace std;
// Definition of used types.
template<typename T> struct dynamic_array {};
template<typename T> struct uvector {};
struct A : public uvector<double> { typedef uvector<double> parent; };
struct C : public A { typedef A parent; };
struct D : public std::array<double,5> { typedef std::array<double,5> parent; };
template<typename T> struct B : public uvector<T> { typedef uvector<T> parent; };
template<typename T> struct container_reference {};
// Catches 'false', A, C, D ======== HERE IT IS !!! ========
template<typename C> struct accepted_dense_vector
{
template<typename C1 = C>
static typename std::enable_if<accepted_dense_vector<typename C1::parent>::value, std::true_type>::type helper(const C&);
static std::false_type helper(...);
constexpr static bool value = decltype(helper(std::declval<C>()))::value;
};
// Catches C<T>
template<template<typename> class C, typename T>
struct accepted_dense_vector<C<T>>
{
constexpr static bool value = std::is_arithmetic<T>::value &&
(std::is_base_of<uvector<T>, C<T>>::value || std::is_base_of<dynamic_array<T>, C<T>>::value);
};
// Catches std::array<T,S>
template<typename T, size_t S>
struct accepted_dense_vector<std::array<T,S>>
{ constexpr static bool value = std::is_arithmetic<T>::value; };
// Catches container_reference<C>
template<typename C>
struct accepted_dense_vector<container_reference<C>>
{ constexpr static bool value = accepted_dense_vector<C>::value; };
int main()
{ // Tests!
cout << accepted_dense_vector<std::array<double, 5>>::value << endl;
cout << accepted_dense_vector<uvector<double>>::value << endl;
cout << accepted_dense_vector<A>::value << endl;
cout << accepted_dense_vector<D>::value << endl;
cout << accepted_dense_vector<B<int>>::value << endl;
cout << accepted_dense_vector<container_reference<uvector<double>>>::value << endl;
cout << accepted_dense_vector<int>::value << endl;
return 0;
}
您可以进一步使用您的解决方案。首先,您不需要std::enable_if
。代码将更具可读性。然后,不要使用std::true_type
,而是使用一个自定义结构体来调用accepted_dense_vector
:
template<typename T>
struct forwarder
{
constexpr static bool value = accepted_dense_vector<T>::value;
};
template<typename T>
static forwarder<uvector<T>> inherit_uvector(uvector<T>*);
static std::false_type inherit_uvector(...);
然后,通过继承uvector<T>
来了解类型是否满足accepted...
,只需使用以下行:
constexpr static bool is_uvector = decltype(inherit_uvector(new C()))::value;
// C is the template parameter of accepted_dense_vector
这是如何工作的?
- 如果
C
继承uvector<T>
,则选择第一个静态函数,decltype将返回forwarder<uvector<T>>
。然后,'调用'::value
将调用accepted...
。 - else,如果
C
没有继承uvector<T>
,则选择第二个函数,decltype将返回std::false_type
。
同样的技巧也可以用于其他继承。同样,B<T>
被accepted...
的第二个专门化捕获。因此,不再需要::parent
类型定义。
下面是完整的代码:
#include <iostream>
#include <array>
#include <string>
using namespace std;
// Definition of used types.
template<typename T> struct uvector {};
template<typename T> struct dynamic_array {};
template<typename T> struct container_reference {};
struct A : public uvector<double> {};
template<typename T> struct B : public uvector<T> {};
struct C : public A {};
struct D : public std::array<double,5> {};
struct E : public uvector<string> {};
struct F : public std::array<string,16> {};
// Catches 'false', A, C, D ======== HERE IT IS !!! ========
template<typename C>
struct accepted_dense_vector
{
template<typename T>
struct forwarder
{
constexpr static bool value = accepted_dense_vector<T>::value;
};
// uvector
template<typename T>
static forwarder<uvector<T>> inherit_uvector(uvector<T>*);
static std::false_type inherit_uvector(...);
// std::array
template<typename T, size_t S>
static forwarder<std::array<T,S>> inherit_stdarray(std::array<T,S>*);
static std::false_type inherit_stdarray(...);
// same for dynamic_array<T>
constexpr static bool is_uvector = decltype(inherit_uvector(new C()))::value;
constexpr static bool is_stdarray = decltype(inherit_stdarray(new C()))::value;
constexpr static bool value = is_uvector || is_stdarray;
};
// Catches C<T>
// /! Also catches anything which is template<typename> class (for example, B)
// => B::parent is not needed, because of the use of std::is_base_of
template<template<typename> class C, typename T>
struct accepted_dense_vector<C<T>>
{
constexpr static bool value = std::is_arithmetic<T>::value &&
(std::is_base_of<uvector<T>, C<T>>::value || std::is_base_of<dynamic_array<T>, C<T>>::value);
};
// Catches std::array<T,S>
template<typename T, size_t S>
struct accepted_dense_vector<std::array<T,S>>
{
constexpr static bool value = std::is_arithmetic<T>::value;
};
// Catches container_reference<C>
template<typename C>
struct accepted_dense_vector<container_reference<C>>
{
constexpr static bool value = accepted_dense_vector<C>::value;
};
int main()
{ // Tests!
cout << "array = " << accepted_dense_vector<std::array<double, 5>>::value << endl;
cout << "uvector = " << accepted_dense_vector<uvector<double>>::value << endl;
cout << "ref = " << accepted_dense_vector<container_reference<uvector<double>>>::value << endl;
cout << "A = " << accepted_dense_vector<A>::value << endl;
cout << "B = " << accepted_dense_vector<B<int>>::value << endl;
cout << "C = " << accepted_dense_vector<C>::value << endl;
cout << "D = " << accepted_dense_vector<D>::value << endl;
cout << "E = " << accepted_dense_vector<E>::value << endl;
cout << "F = " << accepted_dense_vector<F>::value << endl;
cout << "int = " << accepted_dense_vector<int>::value << endl;
return 0;
}
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 受约束的成员函数和显式模板实例化
- 对显式实例化的模板函数的未定义引用
- 用部分实例化的祖先类代替完全实例化的类