用户定义的文字无法包含另一个文件

时间:2020-07-28 14:48:48

标签: c++ include user-defined-literals cxxtest

我有一个Komp类,其中有一个用户定义的文字constexpr Komp operator""_i(long double x),用于从Komp k = 1 + 5.0_i;生成komp对象。

这在 komp.cpp 的main()中工作正常,但是当我在testing.cpp中编写相同的确切语句时(其中包括 komp.h )我得到下面的错误。 komp.h 中的所有其他函数在 testing.cpp 中均能正常工作。我希望用户定义的文字会与其他函数一起被包含。

为什么用户定义的文字在 testing.cpp 中不起作用,而其他功能却如此?

错误:

Undefined symbols for architecture x86_64:
  "operator"" _i(long double)", referenced from:
      MyTestSuite::test5() in komp_testrunner-d3c20f.o
ld: symbol(s) not found for architecture x86_64

// komp.cpp
class Komp {
    private:
        double val1;
        double val2;
    public: 
        // ... Bunch of member-function headers
        constexpr Komp(const double x, const double y) : val1(x), val2(y) {}
        double v1() {return val1;}
        double v2() {return val2;}
};
// ... Bunch of member and non-member functions.
Komp operator+ (const double lhs, const Komp rhs) { // overloads + operator for: double + Komp
    return Komp(lhs+rhs.v1(), rhs.v2());
}
constexpr Komp operator""_i(long double x) { // To match i.e Komp k = 1 + 2.3_i
    return Komp(0.0, x);
}
constexpr Komp operator""_i(unsigned long long x) { // To match i.e Komp k = 1 + 2_i
    return Komp(0.0, x*1.0);
}
int main() { // Only here temporarily for testing purposes
    Komp k = 1 + 2.0_i; // Works here
}
// komp.h
#include <string>
#ifndef KOMP_H
#define KOMP_H
class Komp
{
    public: 
        double val1;
        double val2;
        // ...
        Komp(const double x, const double y);
};
// ...
Komp operator+ (const double lhs, const Komp rhs);
Komp operator ""_i(long double arg);
Komp operator ""_i(unsigned long long arg);
#endif  
#include "komp.h"
#include <cxxtest/TestSuite.h>

class Testing : public CxxTest::TestSuite {
  public:
    void literalTest () {
      Komp c = 3.0 + Komp(2.0, 2.0); // Works fine. No problem with overloading + operator
      Komp b = 5.0 + 2.0_i; // Causing an error
      Komp c = Komp(1.0, 2.0);
      TS_ASSERT(b != c); 
    }
};

1 个答案:

答案 0 :(得分:1)

此函数声明:

Komp operator ""_i(long double arg);

testing.cpp或包含Komp.h的任何文件中唯一可见的文件。但是,您尚未在任何地方定义此功能。

请注意,此定义:

constexpr Komp operator""_i(long double x) { // To match i.e Komp k = 1 + 2.3_i
    return Komp(0.0, x);
}

constexpr,所以它是一个不同的函数。只需在constexpr中将函数声明为Komp.h

此外,您已经在KompKomp.cpp中定义了Komp.h类。从技术上讲这是合法的,但前提是两个定义都相同。在您的情况下,定义是不同的,这违反了 one-definition-rule ,这意味着您的程序具有未定义的行为。您只能在Komp中定义Komp.h