基础/派生模板类类型

Jim*_*lay 2 c++ inheritance templates c++11

我有一个围绕a构建的模板类std::vector.看起来像...

template <class T>
class Vector {
public:
    std::vector<T> vec;

    // Constructors...
    // Operator overloads...
    // Methods...
    // etc.
};
Run Code Online (Sandbox Code Playgroud)

我想创建一个派生模板类,ComplexVector它需要数据类型std::complex<T>,当然我想重用我在课堂上创建的方法,操作符重载等Vector.

问题是,似乎有两种方法可以做到这一点.

1)强制声明std::complex<T>为模板类型.

ComplexVector< std::complex<float> > myVec;
Run Code Online (Sandbox Code Playgroud)

2)ComplexVector仅使用标量类型声明,但然后将std::complex类型传递给Vector构造函数.

ComplexVector<float> myVec;
// Constructor
ComplexVector<T>::ComplexVector() : Vector< std::complex<T> >
Run Code Online (Sandbox Code Playgroud)

选项1在开发软件方面要简单得多,但对用户来说却很难看,而选项2对用户来说要好得多.我想做选项#2,但我担心它会如何运作.

如果我传递std::vector<T>给基类的构造函数,那只会改变构造函数的作用,还是整个模板会从类型T转到std::complex< T >

如果它没有全部转换为std::complex<T>,这是否意味着我必须重载所有的方法Vector

Tel*_*kis 9

模板化的typedef

如果你真的不想进行专业化,你可以简单地使用模板化的typedef,如下所示:

template <typename T>
using ComplexVector = Vector<std::complex<T>>;
Run Code Online (Sandbox Code Playgroud)

然后用户可以使用ComplexVector<float>它,它将正确代表一个Vector<std::complex<T>>.
这是一个非常简单的解决方案,不太适合您的需求.针对您的具体问题,请查看以下解决方案.

模仿的遗传

如果您的目标是仅在何时更改特定方法,Tstd::complex<U>必须继承Vector如此:

template <typename T>
class Vector
{
    public:
    bool is_complex() { return false; }
};

template <typename U>
class ComplexVector : Vector<std::complex<U>>
{
  public:
    bool is_complex() { return true; }
};
Run Code Online (Sandbox Code Playgroud)

这也允许您添加仅适用于complex基于Vector的方法.

ComplexVector仅添加方法

如果你想能够"增强" ComplexVector,你可以这样做:

#include <iostream>
#include <complex>

template <typename T>
class Vector
{
  public:
    bool is_complex() { return false; }
};

template <typename U>
class ComplexVector : Vector<std::complex<U>>
{
  public:
    bool is_complex() { return true; }
    bool only_for_complex() { return true; } // Only in ComplexVector
};

int main() {
  Vector<float> float_vec;
  ComplexVector<float> complex_vec;

  std::cout << "Is float_vec complex? " << float_vec.is_complex() << "\n";
  std::cout << "Is complex_vec complex? " << complex_vec.is_complex() << "\n";

  // The following line doesn't compile
  // std::cout << "Is only_for_complex method in float_vec? " << float_vec.only_for_complex() << "\n";
  std::cout << "Is only_for_complex method in complex_vec? " << complex_vec.only_for_complex() << "\n";

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这里工作演示

使用小型特征检查类型

使用一些模板,我们可以创建一个小帮助器来确定给定的类型是否是一个ComplexVector.如果您想在模板繁重的环境中安全地调用特定方法,这可能会派上用场:

// For any type T, value is false.
template <typename T>
struct is_complex_vector
{
    static const bool value = false;
};

// We specialize the struct so that, for any type U,
// passing ComplexVector<U> makes value true
template <>
template <typename U>
struct is_complex_vector<ComplexVector<U>>
{
    static const bool value = true;
};

is_complex_vector<typeof(float_vec)>::value; // is false
is_complex_vector<typeof(complex_vec)>::value; // is true
Run Code Online (Sandbox Code Playgroud)

这是另一个小型演示,用于演示实际中的这种行为
value将在编译时确定.这可能允许您使用一些SFINAE技巧,以便更好地控制程序的流程.(或者,如果您使用的是C++ 17,则可以使用constexpr.)


Dan*_*ani 5

我认为你使用名字T两次感到困惑.这样看:

template<typename T>
class Vector
{ ... }

template<typename U>
class ComplexVector : public Vector<std::complex<U>>
{ ... }

ComplexVector<float>; // U = float, T = std::complex<float>
Run Code Online (Sandbox Code Playgroud)