代码之家  ›  专栏  ›  技术社区  ›  Afshin

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

  •  0
  • Afshin  · 技术社区  · 5 年前

    我正在玩模板来检测不同的字符串文字,我来到下面的代码(用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_t 键入。但我的问题是:

    1. 尽管 u8 前缀是来自C++ 11的,它使用 第八章 只启动C++ 20。所以我如何检测前缀为 u8 在C++ 11和C++ 20之间?
    2. 如何更改模板以检测两者例如 const char* char* 哪个功能相同?我试着用 remove_const<> 但它不起作用,因为它不会移除 const 常量字符* .
    1 回复  |  直到 5 年前
        1
  •  3
  •   Öö Tiib    5 年前
    1. 你无法察觉 char8_t 在像C++ 17这样的语言中没有。因此,必须有constexpr函数,通过检查字符串的内容来检测它是否是UTF-8。这样的功能在 第八章 也。使用 第八章 . C++ 17或更少没有包含这样的函数。

    2. 使用还是? std::is_same_v<std::decay_t<T>, const char*> || std::is_same_v<std::decay_t<T>, char*>

        2
  •  0
  •   Jarod42    5 年前
    1. 那么我如何检测在C++ 11和C++ 20之间以U8为前缀的UTF-8字符串呢?

    字符串类型不能确保编码。

    const char* 可用于utf-8,也可用于拉丁语-1
    以同样的方式 const wchar* 不需要utf-16。

    有一些启发式的方法来检测编码。

    1. 如何更改模板以同时检测const char*和char*哪个函数?我试着用 remove_const<> 但它不起作用,因为它不会移除 const 常量字符* .

    const char * != char* 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";
        }
    }