c++ 根据模板类型返回正确字符编码的SFINAE函数?

nuypyhwy  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(133)

我正在创建一个类,它编写代码字符串,字符串和字符串之间的区别仅仅是在basic_string中放入什么,所以我将把它写为一个模板类。
问题是,内部使用的文字字符串也必须根据类型而改变,所以我结合了宏和SFINAE来创建一个函数,根据类型返回不同的文字字符串。
但是我的代码有一个“没有函数模板的示例匹配参数列表”错误。
这是我的代码:

#include <filesystem>
#include <string>
#include <type_traits>
#include <fstream>
#include "windows.h"

namespace stdfs = std::filesystem;

template <typename T>
class CCodeWriter
{
public:
    CCodeWriter() {};
    ~CCodeWriter() {};

private:
    template <typename U = T, typename std::enable_if_t<std::is_same_v<U, wchar_t>, wchar_t>>
    const std::basic_string_view<U> ConvString(const std::string_view _AstrView, const std::wstring_view _WstrView)
    {
        return _WstrView;
    }

    template <typename U = T, typename std::enable_if_t<std::is_same_v<U, char>, char>>
    const std::basic_string_view<U> ConvString(const std::string_view _AstrView, const std::wstring_view _WstrView)
    {
        return _AstrView;
    }


#define CONV_STRING(str) ConvString(str, L##str)

private:
    int m_iIndentation;
    std::basic_ofstream<T> m_ofs;

public:
    HRESULT Open(stdfs::path const& _path) { return S_OK; }
    bool IsOpen() const { return m_ofs.is_open(); }

    void WriteCode(const std::basic_string_view<T> _strCode)
    {

        ...

        //Error
        m_ofs << CONV_STRING("\t");

        //Error
        m_ofs << ConvString("\t", L"\t");

        ...
    }
};

int main()
{
    CCodeWriter<char> writer;

    writer.WriteCode("HI");

    return 0;
}

除了用手写每个文字字符串之外,没有其他方法吗?
我试图改变参数类型,但我不熟悉SFINAE,所以我尝试的一切都有错误。
我所期望的是,由于SFINAE的属性,当输入类型时返回文字“\t”,当输入类型时返回文字L”\t”<wchar_t>。
有可能吗?

pbgvytdp

pbgvytdp1#

您的enable_if用法不正确,一种可能的用法是

template <typename U = T, std::enable_if_t<std::is_same_v<U, wchar_t>, int> = 0>

目前,当Tchar时,SFINAE重载如下所示

template <typename U = char, char>

因此,显然不能推导出第二char非类型模板参数。
在C++17及更高版本中,可以简单地使用if constexpr

const std::basic_string_view<T> 
ConvString(const std::string_view _AstrView, const std::wstring_view _WstrView)
{
    if constexpr (std::is_same_v<T, char>) { return _AstrView; }
    else { return _WstrView; }
}

您还可以使用std::char_traits<T>::to_char_type('\n')'\n'转换为适当的字符类型。这应该适用于基本字符(特别是\n\t)。

相关问题