Ошибка компилятора пользовательского строкового литерала .. не является переменной

Мне интересно, в чем разница между этими двумя строковыми UDL. В то время как первый компилируется нормально, я получаю сообщение об ошибке со вторым.

Единственная разница в том, что Literal1 использует std::array как хранилище, а Literal2 использует const char *.

Я могу легко создать Literal2 явно, но как только я попытаюсь использовать UDL, компиляция с '"123"' is not a valid template argument of type 'const char*' because '"123"' is not a variable завершится ошибкой. Интересно, что он также хорошо компилируется, если я не инициализирую p в конструкторе.

template < size_t size >
struct Literal1 : std::array<char,size>
{
    constexpr Literal1(char const (&str)[size+1]) { for (size_t ii = 0; ii < size; ++ii) (*this)[ii] = str[ii]; }
};

template < size_t size > Literal1(char const (&str)[size]) -> Literal1<size-1>;
template < Literal1 literal > constexpr auto operator "" _lit1() { return literal; }


template < size_t size >
struct Literal2 
{
    const char* p{};

    constexpr Literal2(char const (&str)[size+1])  : p(str)  {  }
};


template < size_t size > Literal2(char const (&str)[size]) -> Literal2<size-1>;
template < Literal2 literal > constexpr auto operator "" _lit2() { return literal; }

int main() {

    constexpr auto l1 = "123"_lit1;

    constexpr auto l2 = "123"_lit2; // Compiler error....
    constexpr Literal2 l3{"123"}; // Works...
}

Кто-нибудь может мне объяснить, в чем разница? Почему не работает UDL?

Интересно, что среди компиляторов тоже есть разногласия. GCC ведет себя, как описано выше, в то время как clang жалуется на оба определения UDL. Возможно, шаблон UDL C ++ не полностью реализован в clang, потому что мой пример — это в основном то, что показано на эту страницу cppreference (в самом низу).

Живой пример здесь.

Я еще не владею этой новой функцией, но замена const char* p{}; на char p[size]; и копирование символов один за другим аналогично случаю Literal1, похоже, компилируются на gcc.   —  person florestan    schedule 24.01.2021

См. также:  Как использовать указатель функции для возврата указателя функции?
Понравилась статья? Поделиться с друзьями:
IT Шеф
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: