无法完全专用化字符串文本的模板
Unable to fully specialize template for string literals
我正在创建自己的lexical_cast
函数来包装Boost,bool
类型具有特殊行为,并且还避免了Boost的词法强制转换函数的异常版本。
我完全专注于bool
的功能,以便我可以将iostreams用于std::boolalpha
操纵器。但是,我无法让它适用于字符串文字。完整代码如下,以及指向实时示例的链接:
template<typename T1, typename T2>
T1 lexical_cast(T2 const& value, T1 const& defaultValue = T1{})
{
std::cout << "Generic Conversionn";
T1 convertedValue;
if (!boost::conversion::try_lexical_convert(value, convertedValue))
{
return defaultValue;
}
return convertedValue;
}
template<>
bool lexical_cast<bool, char const*>(char const* const& value, bool const& defaultValue)
{
std::cout << "Specialized c string to booln";
bool convertedValue;
std::istringstream ss(value);
if (!(ss >> std::boolalpha >> convertedValue))
{
std::cout << "Failed string to booln";
return defaultValue;
}
return convertedValue;
}
template<>
bool lexical_cast<bool, std::string>(std::string const& value, bool const& defaultValue)
{
std::cout << "Specialized string to booln";
return lexical_cast<bool>(value.c_str(), defaultValue);
}
template<>
std::string lexical_cast<std::string, bool>(bool const& value, std::string const& defaultValue)
{
std::cout << "Specialized bool to stringn";
std::ostringstream ss;
if (!(ss << std::boolalpha << value))
{
std::cout << "Failed bool to stringn";
return defaultValue;
}
return ss.str();
}
int main()
{
lexical_cast<std::string>(3.14f);
lexical_cast<float>("3.14");
lexical_cast<int>("3.14");
lexical_cast<bool>("true");
lexical_cast<std::string>(true);
}
现场样品
上面的代码给了我输出:
Generic Conversion
Generic Conversion
Generic Conversion
Generic Conversion
Specialized bool to string
上面main
测试中的第 4 种情况不应该是"泛型转换",它应该使用 C 字符串专用化。
我觉得我在这里掉进了一个模板肮脏的兔子洞,对于看似简单的事情来说,解决方案很快就会变得混乱和复杂。对于我想要做的事情,理想的解决方案是什么?我如何让布尔专业化按照我想要的方式工作?
编辑
澄清要求:我知道字符串文字实际上是字符数组。在我上面的例子中,我无论如何都尝试使用char*
,因为接受一个 char 数组需要另一个非类型模板参数,我马上就知道我不能使用它,因为它需要部分专门化我的函数模板,这是非法的。
其次,我意识到也可以使用重载,但我不允许在不为返回类型指定模板参数的情况下可以使用lexical_cast
的情况。比如我必须做lexical_cast<bool>("true")
,我不能做lexical_cast("true")
。我的目标是保持与boost::lexical_cast
接口兼容,它没有可以省略模板参数的情况。
因为我在调用lexical_cast
时必须使用模板语法,所以我觉得我被迫使用全功能专用化。
您必须记住,字符串文字实际上是const
字符的数组。
让函数接受字符串文字的正确方法是这样的:
template<size_t N>
void function(char const (&string)[N]);
不要忘记大小N
包括空终止符。
感谢大家在这里的调查,它激发了我自己的一些想法,我想我找到了一个令人满意的解决方案。关键是使用模板覆盖,这是此线程中其他人的提示。感谢大家的帮助。这是解决方案:
template<typename T1, typename T2>
T1 lexical_cast(T2 const& value, T1 const& defaultValue = T1{})
{
std::cout << "Generic Conversionn";
T1 convertedValue;
if (!boost::conversion::try_lexical_convert(value, convertedValue))
{
return defaultValue;
}
return convertedValue;
}
template<>
std::string lexical_cast<std::string, bool>(bool const& value, std::string const& defaultValue)
{
std::cout << "Specialized bool to stringn";
std::ostringstream ss;
if (!(ss << std::boolalpha << value))
{
std::cout << "Failed bool to stringn";
return defaultValue;
}
return ss.str();
}
template<typename B>
std::enable_if_t<std::is_same<B, bool>::value, B>
lexical_cast(char const* value, bool defaultValue = {})
{
std::cout << "Specialized c string to booln";
bool convertedValue;
std::istringstream ss(value);
if (!(ss >> std::boolalpha >> convertedValue))
{
std::cout << "Failed string to booln";
return defaultValue;
}
return convertedValue;
}
template<typename B>
std::enable_if_t<std::is_same<B, bool>::value, B>
lexical_cast(std::string const& value, bool defaultValue = {})
{
std::cout << "Specialized string to booln";
return lexical_cast<bool>(value.c_str(), defaultValue);
}
template<typename T>
void PrintResult(T const& result)
{
std::cout << "--- Result: " << result << "n";
}
int main()
{
PrintResult(lexical_cast<std::string>(3.14f));
PrintResult(lexical_cast<float>("3.14"));
PrintResult(lexical_cast<int>("3.14"));
PrintResult(lexical_cast<bool>("true"));
PrintResult(lexical_cast<std::string>(true));
std::string trueString = "true";
PrintResult(lexical_cast<bool>(trueString));
}
输出:
Generic Conversion
--- Result: 3.1400001
Generic Conversion
--- Result: 3.14
Generic Conversion
--- Result: 0
Specialized c string to bool
--- Result: 1
Specialized bool to string
--- Result: true
Specialized string to bool
Specialized c string to bool
--- Result: 1
还有现场样本在这里。
- 在 C++ 中从 8 位 ASCII 字符创建 7 位 ASCII 文本字符串
- cin>>gender 和 cin>>*gender ( c 样式文本字符串)有什么区别
- 是否可以动态检查文本字符串是否是 C++ 中给定类的成员?
- 用Zlib解压缩文本字符串
- 将文本字符串作为常量字符 * 参数传递会导致代码分析器错误
- 来自文本字符串或某种其他机制的代码类自动生成器
- 函数读取最大和min int值,并用文本字符串返回
- 模板代码和文本字符串
- 声明具有常量引用与常量变量的常量文本字符串
- 加密给定的文本字符串-Caesar Cipher
- 如何使用键盘输入和sf ::文本在SFML中添加一种文本框以显示文本字符串
- 在C++代码中,如何让用户在2个文本字符串之间输入一个数字
- 如何将文本从一个文件复制到另一个文件,然后将文本字符串的第一个字母转换为大写
- 从文本字符串推断类型
- 跟踪内存中的文本字符串
- 将字符串变量与整数和文本字符串连接起来的 C++ 字符串流
- 将 char 数组分配给文本字符串 - C++
- 如何修复将文本字符串附加到 C 字符串的错误
- 使用C++读取不同长度的多个文本字符串
- 在C++中创建原始文本字符串,类似于 C# 的"@ string"