【问题标题】:How to use a user defined literal in a header file? [duplicate]如何在头文件中使用用户定义的文字? [复制]
【发布时间】:2018-11-29 06:38:09
【问题描述】:

我在MyLiteral.h 中定义了以下用户定义的文字:

namespace my_literals {
    constexpr uint64_t operator"" _nanoseconds(unsigned long long int value) {
        return value*1000;
    }
}

现在我可以在另一个标题 SomeComponent.h 中使用运算符:

using namespace my_literals;
namespace foo {
    constexpr uint64_t timeout = 10_nanoseconds;
}

但是,我不想被using namespace my_literals 污染范围,因为这将为包括SomeComponent.h 在内的所有*.cpp 文件提供文字定义。

我怎样才能避免这种情况? constexpr uint64_t timeout = my_literals::10_nanoseconds; 在 g++ 中给出数字常量之前的预期 unqualified-id

【问题讨论】:

  • 对不起,我重新打开了,因为重复的答案没有在头文件中的限制,但事实证明解决方案是相同的。我将其作为副本重新关闭。
  • 我认为这根本不是重复的。这是涉嫌重复的更受限制的情况,需要不同的解决方案。另一个问题中接受的答案(此时只有一个)使用了不能在标头中使用的范围和 using namespace 声明。

标签: c++ c++11 c++14 constexpr user-defined-literals


【解决方案1】:

在 C++17 中,使用 constexpr lambda,您可以这样做:

namespace foo {
    constexpr uint64_t timeout = []{ using namespace my_literals; return 10_nanoseconds; }();
}

替代(C++11 及更高版本):

namespace foo {
    constexpr uint64_t timeout = my_literals::operator""_nanoseconds(10);
}

namespace foo {

    namespace detail
    {
        using namespace my_literals;
        constexpr uint64_t timeout = 10_nanoseconds;
    }
    using detail::timeout;
}

【讨论】:

    【解决方案2】:

    你可以通过显式调用操作符来解决这个问题:

    namespace foo {
        constexpr uint64_t timeout = my_literals::operator""_nanoseconds(10);
    }
    

    【讨论】:

    • 非常丑:)
    • @kreuzerkrieg 毫无疑问。不过对于库代码来说这很好。
    • 我可以确认这项工作并包含我的意图。但是,它显然很难看,不再是直观的文字。
    • @Alexander 顺便说一句,你为什么不使用std::chrono 实用程序?
    • @vsz 我认为这是库代码,using namespace 不应该泄露给用户。
    【解决方案3】:

    您可以将using 声明放在命名空间内(如果您不介意foo::operator""_nanoseconds 可用):

    namespace foo {
        using namespace my_literals;
        constexpr uint64_t timeout = 10_nanoseconds;
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多