c++ - 我的类(class)无法识别用户定义的文字运算符

标签 c++ c++11 user-defined-literals

我编写了一个类,它使用文字运算符来指示要在物理应用程序中使用的测量误差。我定义了一个文字 ""_err,它将 long double 作为参数并返回一个名为 Error 的结构。例如,1.3_err

此文字的friend声明放在头文件TStat.h中,定义放在TStat.cpp中,正如您将在下面的代码中看到的那样。

但是,在使用 b = 0.4_err 这样的示例进行编译时出现错误,其中 bError。在错误中它说找不到文字运算符。您可以查看本题末尾的错误信息。

我尝试了很多组合,比如在内部或外部定义文字等。我搜索过类似的问题,但代码中的一切似乎都很好,就像许多教程和其他 C++ 资源所描述的那样。

作为一名粒子物理学家,我使用一个名为 ROOT 的 C/C++ 库由 CERN 开发,实际上是一个 C/C++ 解释器。在那里,我可以毫无错误地使用此类(我根本没有使用任何 ROOT 类)。但是,当我使用 c++11 标志通过 g++ 编译我的代码时,找不到与文字匹配的内容。

这是头文件:

#ifdef TSTAT_H
#define TSTAT_H

namespace TStat {
    struct Error {
        // ...
    }

    class Double {
        // constructors, etc.
        // ...

        friend Error operator "" _err (long double);
    }
}

这是 TStat.cpp 文件:

#include "TStat.h"

using namespace TStat;

// ...

TStat::Error operator"" _err(long double err) {
    TStat::Error error;
    // ...
    return error;
}

在终端中使用以下命令编译时(我使用的是 MacOS)

g++ -Wall -g -std=c++11 example.cpp TStat.cpp -o example.exe

我收到一条错误消息

example.cpp:6:12: error: no matching literal operator for call to
  'operator""_err' with argument of type 'long double' or
  'const char *', and no matching literal operator template
b = 0.4_err;

对于这样的 example.cpp:

#include "TStat.h"

using namespace TStat;

int main() {
    Error b;
    b = 0.4_err;

    return 0;
}

最佳答案

friend 声明不会将声明的名称带入任何其他范围。在这种情况下,它甚至不会将名称带入类本身的范围内:

[class.friend]/7 A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (6.4.1).

但这与显示的案例无关。 main 不会在任何类中看到任何 friend 声明。

最简单的解决方法是在 TStat.h 中声明 operator ""_err 在任何类之外的顶层。

关于c++ - 我的类(class)无法识别用户定义的文字运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57947078/

相关文章:

C++ HTML 生成类

c++11 - 对于已构造的对象,使用 std::move 的 C++11 Push_back() 与 emplace_back() 的效率

c++ - 可变递归模板 mem 有趣的特化

c++ - 是否可以使函数模板对不适当的类型而不是错误执行默认操作?

c++ - 在函数范围外的 header 中使用 UDL

c++ - 在左值上调用用户定义的文字

c++ - 为什么 boost::any 禁止转发 const&&?

c++ - 获取国家域名

c++ - 使用用户定义文字的成员时出现编译错误

c++ - 在这种情况下我可以忽略 C4251 警告吗?