Попытка использовать строковые литералы в качестве параметров шаблона без типа в G CC 10.1. Имейте следующий код:
#include <cstddef>
#include <algorithm>
#include <iostream>
template<std::size_t n> struct fixed_string {
constexpr fixed_string(char const (&s)[n]) {
std::copy_n(s, n, this->el);
}
constexpr fixed_string(fixed_string<n> const& s) {
std::copy_n(s.el, n, this->el);
}
constexpr bool operator==(fixed_string const&) const = default;
constexpr auto operator<=>(fixed_string const&) const = default;
char el[n];
};
template<std::size_t n> fixed_string(char const(&)[n])->fixed_string<n>;
template<fixed_string str>
class Base {
public:
Base() {
std::cout << str.el << std::endl;
}
};
template<fixed_string str>
class Derived : public Base<str> {
};
int main(void) {
Derived<"Hello World"> x;
}
Base
сам по себе отлично работает, пытаясь выяснить, как передать строковые литералы вверх по иерархии классов. Я думал, что конструктор копирования сработает, и G CC выплевывает это прекрасное сообщение об ошибке и смеется над моей попыткой:
error: no matching function for call to ‘fixed_string(fixed_string<...auto...>)’
note: candidate: ‘template<long unsigned int n> fixed_string(const fixed_string<n>&)-> fixed_string<n>’
constexpr fixed_string(fixed_string<n> const& s) {
^~~~~~~~~~~~
note: template argument deduction/substitution failed:
note: mismatched types ‘const fixed_string<n>’ and ‘fixed_string<...auto...>’
Cool. Итак, <...auto...>
- это G CC speak для «Заполнителя выведения шаблона класса» , и я не знаю, как заставить компилятор сопоставить это с моими вызовами функций. Кто-нибудь знает, как сюда принудить G CC? Или, в качестве альтернативы, как распространять строковые литералы через иерархию классов?
Интересный факт, передача str.el
в шаблон Base
приводит к сбою G CC.