在C++中使用模板检测不同字符串

在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

我正在使用模板来检测不同的字符串文本,我得到了以下代码,请使用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 << "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开头的话。