与complex.h一起使用时对static const double的未定义引用

时间:2016-07-07 10:17:15

标签: c++ complex-numbers

这是最小代码:

#include <iostream>
#include <complex>

using namespace std;

class Test {
    static const double dt = 0.1;
public:
    void func();
};

void Test::func() {
    cout << dt << endl; // OK!
    cout << dt*complex<double>(1.0, 1.0) << endl; // Undefined reference
}

int main() {
    Test a;
    a.func();
}

标注的行给出undefined reference to `Test::dt'。每次我想将复数与dt相乘时,我都可以创建一个临时变量,但这很不方便,因为我在代码中复用许多具有复数的静态const成员。

我的猜测是,当dt乘以复数时,由于某种原因,它需要dt的地址(即&dt,这看起来很奇怪。

为什么会出现这种错误以及如何让它在每次我想要将它与一个复数相乘之前比double temp = dt;更优雅地工作?

3 个答案:

答案 0 :(得分:2)

您已声明Test::dt但未在某处定义。如果您决定在类声明之外定义事物 - 您应该保持一致:

#include <iostream>
#include <complex>

using namespace std;

class Test {
    static const double dt;
    public:
    void func();
};

void Test::func() {
    cout << dt << endl; // OK!
    cout << dt*complex<double>(1.0, 1.0) << endl; // Undefined reference
}

const double Test::dt = 0.1;

int main() {
    Test a;
    a.func();
}

答案 1 :(得分:2)

  

......如何让它发挥作用......?

#include <iostream>
#include <complex>

using namespace std;

class Test {
    static const double dt;
public:
    void func();

};

//move initialization outside of class
const double Test::dt = 0.1; 

void Test::func() {
    cout << dt << endl; // OK!
    cout << dt*complex<double>(1.0, 1.0) << endl; // Undefined reference

}

int main() {
    Test a;
    a.func();
}


或(请参阅this question进行解释)

class Test {
        static const double dt = 0.1;
    public:
        void func();

};
const double Test::dt;


或者(与上面的那个相同,但是使用c ++ 11&#39; s constexpr

class Test { 
         static constexpr double dt = 0.1;
    public:   
         void func();    

};                      
constexpr double Test::dt;


  

为什么会出现这种错误?    

来自here

  

如果声明了整数或枚举类型的静态数据成员   const(而不是volatile),可以使用初始化程序初始化   每个表达式都是一个常量表达式,就在里面   班级定义......

因此静态数据成员可以在类定义中初始化,如果类型 int 枚举并声明 const ,这不是你的情况。 (有关详细信息,请参阅this answer

为什么它似乎在为第一线工作?好吧,用clang编译我得到了:

  

警告:类型为&#39; const的静态数据成员的类内初始值设定项   双&#39;是GNU扩展

所以这个浮点类型初始化是gcc编译器的扩展,这个扩展可能不会使用期望引用类型参数的函数(现在只是猜测)。

另请注意,这仅适用于c ++ 98(c ++ 11具有解决此问题的constexpr关键字)

答案 2 :(得分:1)

#include <iostream>
#include <complex>

using namespace std;

class Test {
    static const double dt;
    public:
    void func();
};

void Test::func() {
    cout << dt << endl; // OK!
    cout << dt*complex<double>(1.0, 1.0) << endl; // Undefined reference
}

const double Test::dt = 0.1;

int main() {
    Test a;
    a.func();
}