我写了以下代码:
g++ -x c++ - -std=gnu++11 -Wall -Wextra -Werror -Wconversion <<__EOF && ./a && echo -e "\e[1;31mOK\e[0m" || echo -e "\e[1;31mfailed!\e[0m"
#include <functional>
#include <vector>
#include <cstdint>
template< typename T >
struct traits_type
{
typedef std::uint8_t op_type;
// ... typedefs
};
template< typename T, typename traits = traits_type< T > >
struct generator
{
typedef typename traits::op_type op_type;
// typedefs...
void operator () () const { return; }
template< typename ...OPS >
void operator () (op_type const op, OPS && ...ops)
{
sequence.push_back(op);
return operator () (std::forward< OPS >(ops)...);
}
// member functions etc...
std::vector< op_type > sequence;
};
int main()
{
struct T { }; // Some type, which does not concern us in this context.
generator< T > g;
g(0b00000000, 0b10101010);
g(0b01010101);
// ... using of g.sequence, say, in state machine
return 0;
}
__EOF
按照我的意图,这段代码将允许我创建一些(所谓的)&#34;操作码&#34;的序列。但是0b00000000
的数字文字被视为int。这导致了这样一个事实,即最终将更大的有符号整数类型转换为更小的无符号整数类型。它可能具有不良副作用。没有后缀表示 C ++ 中大小为一个字节的无符号整数类型。
如何使用纯 C ++ 11 来避免这种情况?
我不想使用static_cast
和其他人,因为这会导致代码膨胀(多个括号和至少一个符号来命名static_cast
- 包装函数)。
解决方案可能是使用用户定义的文字,比如0b00000000_op
,它看起来比o(0b00000000)
好。但是运算符必须是一个函数模板,如:
template< template T, typename traits = type_traits< T > >
constexpr
typename traits::op_type
operator "" _op (typename traits::op_type && op)
{
return std::move(op);
}
但在 C ++ 11 中没有这样的语法......如果有T
模板参数怎么办?