bit*_*ask 5 c++ g++ string-literals clang++ c++17
根据我的C++17(草案)版本(16.5.8 [over.literal]) 以及cppreference.com,C++17应该支持用户定义的字符串文字的模板化运算符。
具体来说:
template <char...>
double operator "" _pi() {
return 0.;
}
int main() {
"test"_pi;
}
Run Code Online (Sandbox Code Playgroud)
然而,gcc 和 clang 都对我大喊大叫:
// gcc -Wall -Wextra -pedantic -std=c++17
error: no matching function for call to 'operator""_pi<char, 't', 'e', 's', 't'>()'
7 | "test"_pi;
| ^~~~~~~~~
note: candidate: 'template<char ...<anonymous> > double operator""_pi()'
2 | double operator "" _pi() {
// clang -Wall -Wextra -pedantic -std=c++17
error: no matching literal operator for call to 'operator""_pi' with arguments of types 'const char *' and 'unsigned long', and no matching literal operator template
Run Code Online (Sandbox Code Playgroud)
(现场演示)
他们似乎都想推动我使用以下模板,该模板曾经被简单地认为是 C++17 的一部分,但据我了解并没有成为其中的一部分:
template <typename T, T...>
double operator "" _pi() {
return 0.;
}
Run Code Online (Sandbox Code Playgroud)
然而,gcc 和 clang 都正确地警告这是一个非标准扩展,但它们正确地编译了它。gcc和clang声称完全支持 C++17 核心语言。
我究竟做错了什么?我的草稿和cppreference.com 是否不准确?我目前无法访问最终标准版本。
我的用例是实现以下内容,这就是我需要编译时信息的原因。
template <char... cs>
constexpr auto operator "" _a() {
return std::array<char, sizeof...(cs)>({cs...});
}
// "Hello"_a creates a std::array<char,5>
Run Code Online (Sandbox Code Playgroud)
模板char...用户定义的文字不适用于字符串。它称为数字文字运算符模板,它允许您拥有一个文字运算符,该运算符将获取您正在使用的数字并将其扩展为模板运算符的包。例如,您可以使用像这样的运算符
1234_pi
Run Code Online (Sandbox Code Playgroud)
这将解决调用
operator "" <'1', '2', '3', '4'> _pi()
Run Code Online (Sandbox Code Playgroud)
你想要的东西在库存中是不可能的 C++17
要使其正常工作,您需要升级到 C++20,它允许您使用可以从字符串文字构造的用户定义类型,并使用它来构建std::array. 这就是现在所说的字符串文字运算符模板。那看起来像
template<std::size_t N>
struct MakeArray
{
std::array<char, N> data;
template <std::size_t... Is>
constexpr MakeArray(const char (&arr)[N], std::integer_sequence<std::size_t, Is...>) : data{arr[Is]...} {}
constexpr MakeArray(char const(&arr)[N]) : MakeArray(arr, std::make_integer_sequence<std::size_t, N>())
{}
};
template<MakeArray A>
constexpr auto operator"" _foo()
{
return A.data;
}
Run Code Online (Sandbox Code Playgroud)
进而
"test"_foo;
Run Code Online (Sandbox Code Playgroud)
这将解决一个std::array<char, 5>. 如果您不希望数组中出现空终止符,则只需1从除部分N之外的所有使用它的地方减去即可char const(&arr)[N]。
如果你不能使用 C++20,你可以将其切换到几个函数,例如
template <std::size_t N, std::size_t... Is>
constexpr auto as_array_helper(const char (&arr)[N], std::integer_sequence<std::size_t, Is...>)
{
return std::array<char, N>{arr[Is]...};
}
template <std::size_t N>
constexpr auto as_array(const char (&arr)[N])
{
return as_array_helper(arr, std::make_integer_sequence<std::size_t, N>());
}
Run Code Online (Sandbox Code Playgroud)
然后你会像这样使用它
as_array("test")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1099 次 |
| 最近记录: |