在C++中使用模板检测不同字符串
我正在使用模板来检测不同的字符串文本,我得到了以下代码,请使用C++20进行尝试:在C++中使用模板检测不同字符串,c++,c++20,C++,C++20,我正在使用模板来检测不同的字符串文本,我得到了以下代码,请使用C++20进行尝试: #include <iostream> #include <type_traits> template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, const char*>, int> = 0> void print_str(T) { std::cout
#include <iostream>
#include <type_traits>
template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, const char*>, int> = 0>
void print_str(T) {
std::cout << "char* print_str\n";
}
template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, const char8_t*>, int> = 0>
void print_str(T) {
std::cout << "char8_t* print_str\n";
}
template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, const wchar_t*>, int> = 0>
void print_str(T) {
std::cout << "wchar_t* print_str\n";
}
int main() {
auto a = "hello"; // prints "char* print_str"
print_str(a);
auto b = L"hello"; // prints "wchar_t* print_str"
print_str(b);
auto c = u8"hello"; // prints "char8_t* print_str"
print_str(c);
}
我使用的事实是,在C++20中,u8前缀声明char8\u t类型。但我的问题是:
尽管u8前缀来自C++11,但它仅在启动C++20时使用字符8。那么,如何在C++11和C++20之间检测以u8为前缀的UTF-8字符串呢?
如何更改模板以同时检测const char*和char*哪个函数?我试图使用remove_const,但它不起作用,因为它无法从const char*中删除const。
在像C++17这样没有字符的语言中,您无法检测到字符。所以您必须使用constexpr函数,通过检查字符串的内容来检测它是否为UTF-8。这种函数对char8\t也有意义。使用char8\u t构造非法UTF-8字符串很简单。C++17或更低版本不包含此类函数
用还是用?std::is_same|v | std::is_same|v
在像C++17这样没有字符的语言中,您无法检测到字符。所以您必须使用constexpr函数,通过检查字符串的内容来检测它是否为UTF-8。这种函数对char8\t也有意义。使用char8\u t构造非法UTF-8字符串很简单。C++17或更低版本不包含此类函数
用还是用?std::is_same|v | std::is_same|v
那么,如何在C++11和C++20之间检测以u8为前缀的UTF-8字符串呢?
字符串的类型不能确保编码
const char*可用于utf-8,也可用于拉丁语-1
同样,常量wchar*也不是utf-16所必需的
有一些启发式方法可以检测编码
如何更改模板以同时检测const char*和char*哪个函数?我试图使用remove_const,但它不起作用,因为它无法从const char*中删除const。
常量字符*!=字符*常量
您可以从后者中删除const以获得char*
你可以
std::is_same_v<std::remove_const_t<std::remove_pointer_t<T>>, char> && std::is_pointer_v<T>
但只需改为:
void print_str(const char*) { std::cout << "char* print_str\n"; }
void print_str(const char8_t*) { std::cout << "char8_t* print_str\n"; }
void print_str(const wchar_t*) { std::cout << "wchar_t* print_str\n"; }
如果您坚持使用模板:
template <typename T>
void print_str(const T*) {
if constexpr (std::is_same_v<char, T>) {
std::cout << "char* print_str\n";
} else if constexpr (std::is_same_v<char8_t, T>) {
std::cout << "char8_t* print_str\n";
} else if constexpr (std::is_same_v<wchar_t, T>) {
std::cout << "wchar_t* print_str\n";
}
}
那么,如何在C++11和C++20之间检测以u8为前缀的UTF-8字符串呢?
字符串的类型不能确保编码
const char*可用于utf-8,也可用于拉丁语-1
同样,常量wchar*也不是utf-16所必需的
有一些启发式方法可以检测编码
如何更改模板以同时检测const char*和char*哪个函数?我试图使用remove_const,但它不起作用,因为它无法从const char*中删除const。
常量字符*!=字符*常量
您可以从后者中删除const以获得char*
你可以
std::is_same_v<std::remove_const_t<std::remove_pointer_t<T>>, char> && std::is_pointer_v<T>
但只需改为:
void print_str(const char*) { std::cout << "char* print_str\n"; }
void print_str(const char8_t*) { std::cout << "char8_t* print_str\n"; }
void print_str(const wchar_t*) { std::cout << "wchar_t* print_str\n"; }
如果您坚持使用模板:
template <typename T>
void print_str(const T*) {
if constexpr (std::is_same_v<char, T>) {
std::cout << "char* print_str\n";
} else if constexpr (std::is_same_v<char8_t, T>) {
std::cout << "char8_t* print_str\n";
} else if constexpr (std::is_same_v<wchar_t, T>) {
std::cout << "wchar_t* print_str\n";
}
}
以下是我的问题-请坚持每个Stackowerflow帖子一个问题。如果remove_const removed const from您的const char*,您希望如何处理它?您不能修改常数。对于第二个问题,您可以添加一个| | std::is|u same_v@JesperJuhl我想泛化模板,使函数也能用于非文字字符串。以下是我的问题-请坚持每个Stackowerflow帖子一个问题。如果remove_const removed const from const char*,你希望能用它做什么?您不能修改常数。对于第二个问题,您可以添加一个| | std::is|u same_v@JesperJuhl我想对模板进行泛化,使函数也适用于非文字字符串。我还不熟悉模板,所以我忘了我可以使用| |。我还不熟悉模板,所以我忘了我可以使用| |。我知道那种类型的字符串不能确保编码。但我想以某种方式区分普通字符串和u8字符串,并在u8不是UTF-8时抛出异常。所以我可以有一个打印UTF-8字符串的函数,如果它真的是以u8开头的话。我知道这种类型的字符串不能确保编码。但我想以某种方式区分普通字符串和u8字符串,并在u8不是UTF-8时抛出异常。所以我可以有一个打印UTF-8字符串的函数,如果它真的是以u8开头的话。