Мне интересно, в чем разница между этими двумя строковыми 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