Обходной путь для ошибки gcc: использование chrono_literals в шаблоне разрывает string_literals

В GCC 4.9.2 следующий код не компилируется:

#include <chrono>
#include <string>

using namespace std::literals::string_literals;
using namespace std::literals::chrono_literals;

template<typename T>
struct S
{
    S()
    {
        "hello"s;
    }
};

int main()
{
    S<int> s;
}

выдает ошибки, начинающиеся с:

error: no matching function for call to 'operator""s()'

Нет ошибок, если я закомментирую строку chrono_literals, и нет ошибок для класса, не являющегося шаблоном.


Я предполагаю, что это ошибка gcc 4.9, поскольку тот же код работает в GCC 5 и clang. Мой вопрос: есть ли обходной путь, который я могу использовать, чтобы я мог использовать как литералы std::string, так и литералы chrono в шаблоне с этой версией компилятора?

Например, что-то, что я мог бы отредактировать в одном из стандартных заголовков, или что-то, что я мог бы сделать глобально в своем коде?

Примечание: эта версия компилятора не имеет подразумеваемого using namespace std::literals::chrono_literals, как это предписывает стандарт C++; это также было добавлено в GCC 5.


person M.M    schedule 08.04.2016    source источник
comment
Вам нужно иметь using на верхнем уровне? Вам нужно использовать оба в одной и той же функции? Тот же объем?   -  person Dan Mašek    schedule 08.04.2016


Ответы (1)


Если вам не нужно использовать оба в одной и той же области, просто используйте using там, где это необходимо.

В противном случае я бы переопределил свои собственные строковые литералы на основе заголовок libstdc++ и назовите их как-то иначе, чем s (о чем вы все равно получите предупреждение)... скажем, _s. Конечно, вы также можете реализовать свой собственный хронолитералы, но они кажутся более сложными.

#include <string>   
#include <chrono>


inline std::basic_string<char>
operator""_s(const char* __str, size_t __len)
{ return std::basic_string<char>{__str, __len}; }


template<typename T>
struct S
{
    S()
    {
        {
            using namespace std::literals::chrono_literals;
            10s;
            "hello"_s;
        }
        {
            using namespace std::literals::string_literals;
            "hello"s;
        }
    }
};

int main()
{
    S<int> s;
}

код на godbolt

person Dan Mašek    schedule 08.04.2016