如何将来自用户定义文字的可变char模板参数转换回数字类型
How can variadic char template arguments from user defined literals be converted back into numeric types?
这个问题是因为这个。
c++ 11允许您为数字字面值定义如下的字面值:
template<char...> OutputType operator "" _suffix();
意味着503_suffix
会变成<'5','0','3'>
这很好,尽管在它的形式中不是很有用。
如何将其转换回数字类型?这将把<'5','0','3'>
变成constexpr
503
。此外,它还必须处理浮点量。<'5','.','3>
会变成int 5
或float 5.3
在上一个问题中找到了部分解决方案,但它不适用于非整数:
template <typename t>
constexpr t pow(t base, int exp) {
return (exp > 0) ? base * pow(base, exp-1) : 1;
};
template <char...> struct literal;
template <> struct literal<> {
static const unsigned int to_int = 0;
};
template <char c, char ...cv> struct literal<c, cv...> {
static const unsigned int to_int = (c - '0') * pow(10, sizeof...(cv)) + literal<cv...>::to_int;
};
// use: literal<...>::to_int
// literal<'1','.','5'>::to_int doesn't work
// literal<'1','.','5'>::to_float not implemented
总有简单的方法。非类型形参包可以按如下方式展开为初始化列表:
#include <iostream>
template<char... Chars>
double
operator "" _suffix()
{
const char str[]{Chars..., ' '};
return atof(str);
}
int
main()
{
std::cout << 123.456789_suffix << std::endl;
}
我认为以下应该在没有指数部分(未经测试)的浮点数上工作:
template<bool fp, long long num, long long denom, char ...> struct literal;
template<bool fp, long long num, long long denom> struct literal<fp, num, denom>
{
static constexpr double value() { return (1.0*num)/denom; }
};
template<long long num, long long denom, char digit, char... rest>
struct literal<false, num, denom, digit, rest...>
{
static constexpr double value()
{
return literal<false, 10*num + (digit-'0'), denom, rest...>::value();
}
};
template<long long num, long long denom, char digit, char... rest>
struct literal<true, num, denom, digit, rest...>
{
static constexpr double value()
{
return literal<true, 10*num + (digit-'0'), 10*denom, rest...>::value();
}
};
template<long long num, long long denom, char... rest>
struct literal<false, num, denom, '.', rest...>
{
static constexpr double value()
{
return literal<true, num, denom, rest...>::value();
}
};
template<char... c> double operator "" _dbl()
{
return literal<false, 0, 1, c...>::value();
}
如何将其推广到指数部分应该是显而易见的。
当然还需要做一些错误检查(确保字符确实是数字)。
相关文章:
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 从 C# GUI 将 char * 参数传递给C++ dll 函数
- Swift Call C 方法带有char **参数,并且需要操作char **参数
- 使用"const char*"和"char*"参数连接两个第三方模块
- 将 char * 参数传递给 C# 函数
- 使用 char[] 参数通过 JNI 调用方法
- C# PInvoke - 返回 char* 和引用 char* 参数的函数
- 导出托管的C#函数将返回更改CHAR*参数为未托管的代码
- 即使在 Visual C++ 编译器中,在模板中传递 "const char" 参数也有些麻烦 2013 年 11 月 CTP
- 将'const char*'参数发送到接收'const char* &'的函数
- discover char*参数大小
- lambda接受“char”参数
- 在编译模板方面,char、有符号char或无符号char参数类型的函数重载
- 将类方法传递给const char*参数
- Atoi 仅返回 char* 参数的第一个数字
- 专门化模板成员函数来处理std::string和char[]参数
- 带有 char* 参数的 cout <<打印字符串,而不是指针值
- 带有char[]参数的c++模板
- GetModuleBaseName dosen't take char* 参数
- 以双精度数除以双精度数来获得循环中的余数和char参数不起作用