Как использовать пользовательский литерал в заголовочном файле?

Я определил следующий пользовательский литерал в 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потому что это дало бы буквальное определение всем *.cpp файлы, которые включают SomeComponent.h,

Как я могу избежать этого? constexpr uint64_t timeout = my_literals::10_nanoseconds; дает ожидаемый неквалифицированный идентификатор перед числовой константой в g++.

3 ответа

В 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;
}

Вы можете обойти это, вызвав оператор явно:

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

Вы могли бы поставить using объявление внутри пространства имен (если вы не против foo::operator""_nanoseconds имеется в наличии):

namespace foo {
    using namespace my_literals;
    constexpr uint64_t timeout = 10_nanoseconds;
}
Другие вопросы по тегам