gpt4 book ai didi

c++ - 用部分实例化的祖先类替换完全实例化的类

转载 作者:太空宇宙 更新时间:2023-11-04 11:57:07 25 4
gpt4 key购买 nike

我要accepted_dense_vector<??>::value返回 'true'当我以以下形式提供模板参数时:

C<T>什么时候Cuvector , dynamic_arrayTstd::is_arithmetic .

std::array<T,S>什么时候Tstd::is_arithmetic .

container_reference<C>什么时候accepted_dense_vector<C>::value是“真实的”。

一切正常,但在派生的、完全实例化的类 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(...);

然后,知道类型是否满足accepted...通过继承uvector<T> ,只需使用以下行:

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... .
  • 否则,如果C不继承 uvector<T> ,选择第二个函数,decltype 将返回 std::false_type .

同样的技巧可以用于其他继承。另外,B<T>被第二个专业抓到accepted... .因此,::parent不再需要 typedef。

这是完整的代码(live here):

#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++ - 用部分实例化的祖先类替换完全实例化的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15740553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com