1

我正在开发一种算法,我需要根据输入变量将一个向量定义为实数或复数。伪就像

void foo(bool is_real)
{
  if (is_real)
  {
    vector< double > v; 
  }
  else vector< complex > v;
}

现在我正在编写两个不同版本的算法,如果 is_real 为真,我将算法用于真实情况,否则,使用复杂情况。实际上,除了数据类型之外,这两种算法都是完全相同的。所以我用谷歌搜索

#if is_real
  vector< double > v;
#else
  vector< complex > v;
#endif

但是这段代码无法编译。我正在使用 linux gnu c++ 4.7.2。我想知道该宏是否仅适用于 microsoft c++?我觉得不舒服,因为在我的实现中唯一的区别是数据类型,有没有办法选择在运行时应该使用什么类型?谢谢。

4

4 回答 4

10

如果代码完全相同,则将其设为模板:

namespace detail {
    template <typename T>
    void foo() {
        vector<T> v;
        // blah
    }
}

void foo(bool is_real)
{
  if (is_real)
  {
    detail::foo<double>();
  }
  else detail::foo<complex>();
}
于 2013-08-05T08:31:28.047 回答
1

C++ 模板需要在编译时知道它们的类型。在您的第一个示例中,类型是在运行时定义的,这在 C++ 中是不允许的,这是一种相当静态的语言。第二个示例使用编译时条件,所以很好。

于 2013-08-05T08:34:52.157 回答
1

宏由预处理器使用,它是编译时指令,您不能在运行时使用它。它假定您将定义一些东西并让编译器知道您在编译期间使用的是实数或复数。

您可以使用模板(如建议的那样),但如果您希望在一个地方初始化它,然后继续使用向量,您有几个选择 -

  1. 使用继承并使用基类的向量
  2. 有两个向量并且只能使用一个(取决于输入)
  3. 将您的实数存储为复数。不过有点浪费。
于 2013-08-05T08:39:44.043 回答
0

您尝试实现的目标is_real可以在编译时使用-Dis_real选项完成

在运行时你可以有这样的东西:

template<typename T>
class MyAlgorithm
{
    public:

    MyAlgorithm(/*...*/ )
    {
        /*Your initialization routine */
    }

     /* copy constructor
     copy assignment operator */

    ~MyAlgorithm(/*...*/){ /*...Other deallocation stuffs...*/ }

    private:
        std::vector<T> vec;
};

int main ()
{

    MyAlgorithm<double> m;
    MyAlgorithm<std::complex<double> > n;

      return 0;
}
于 2013-08-05T08:43:26.063 回答