提问人:Tee Mo 提问时间:6/30/2023 更新时间:6/30/2023 访问量:49
SFINAE 函数,根据模板类型返回正确的字符编码?
SFINAE function that returns proper character encoding depending on template type?
问:
我正在创建一个编写代码字符串的类, string 和 wring 之间的区别只是放在basic_string中的内容,所以我打算把它写成一个模板类。
问题在于内部使用的文本字符串也必须根据 Type 进行更改,因此我将宏和 SFINAE 组合在一起,创建了一个函数,该函数根据 Type 返回不同的文本字符串。
但是我的代码有一个“没有函数模板的实例与参数列表匹配”错误。
这是我的代码:
#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”,输入<wchar_t>类型时返回文字 L“\t”。
可能吗?
答:
4赞
Holt
6/30/2023
#1
您的用法不正确,一种可能的用法是enable_if
template <typename U = T, std::enable_if_t<std::is_same_v<U, wchar_t>, int> = 0>
目前,您的 SFINAE 重载如下所示T
char
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
评论
L##str
是错误的(是创建标识符)(GCC 拒绝它)。使用(让连接 C 字符串文字)有效。##
L"" str