有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
Is there a way to define traits and cast operators for redefined, via `typedef`, basic types?
我已经编写了一对转换器函数,用于在以弧度表示的角度的浮点表示和二进制角度(又名BAMS(之间进行转换:
// Binary angles that maps into 360 degree circle
typedef uint8_t binang8_t;
typedef uint16_t binang16_t;
typedef uint32_t binang32_t;
typedef uint64_t binang64_t;
// Convert from radians to BAMS
template<typename A, typename T> A to_binang(T val);
// Convert from radians or BAMS
template<typename T, typename A> T to_rads(A val);
主要问题是我为在转换器中使用而创建的is_binangle
特性不能防止使用无符号整数代替新类型我知道,我可以将这些新类型定义为结构,这将解决这个问题,但我有理由不将它们声明为class
或struct
(以避免重新定义算术运算符并与旧的C有效负载标头保持兼容(。有什么技巧可以让它与使用typedef
定义的类型一起工作吗?以下是我实现这一特性的尝试:
template<typename T> struct is_binangle {
static const bool value = false;
};
template<> struct is_binangle<binang8_t> {
static const bool value = true;
};
template<> struct is_binangle<binang16_t> {
static const bool value = true;
};
...
理想情况下,我更喜欢为这些类型定义自定义类型转换,这样就可以通过以下方式进行转换:
double rangle = M_PI/6;
binang16_t bang = binang16_t(rangle);
bang += bang;
double another_rangle = double(another_bang);
我强烈怀疑,除非这些二元角是classes
/structures
,否则这是不可能的。对吗?
您可以将enum
用于以下目的:
#include <cstdint>
#include <type_traits>
enum binang8_t : uint8_t {};
template <typename T>
struct is_binang : std::false_type {};
template <>
struct is_binang<binang8_t> : std::true_type {};
// static_assert(is_binang<uint8_t>::value); --> This fails
static_assert(is_binang<binang8_t>::value);
extern "C" void some_c_function(uint8_t);
int main() {
binang8_t val = static_cast<binang8_t>(0);
some_c_function(val);
return 0;
}
(编译器资源管理器(
这是因为无范围枚举是唯一类型的(与它们的基础整数类型不同(,并且它们可以隐式转换为整数(因此您可以将它们传递给C函数,该函数接受整数而不进行强制转换(。
我承认,这并不完美,因为如果你进行算术运算,你必须将结果返回到binang8_t
,而且它对浮点不起作用。
这是一个半答案(一个模板类取代了这4个typedef
-s(,但还有另一个问题——课本成员模板函数实现失败(
希望我能够说服C程序员相信C++的数组
struct blah {
uint16_t value;
};
可以被视为uint16_t
值的数组,我确实尝试过声明class
:
template<typename UnsignedInt,
std::enable_if_t<std::is_unsigned<UnsignedInt>::value, int> = 0>
class binangle {
UnsignedInt value;
public:
binangle(UnsignedInt v) : value(v) {}
template<typename F>
binangle(F v) { set_from_radians<F>(v); }
template<typename F>
void set_from_radians(F rad);
template<typename F>
void set_from_degrees(F rad);
template<typename F>
F to_radians(int start_deg = 0) const;
template<typename F>
F to_degrees(int start_deg = 0) const;
template<typename F> operator F() const;
explicit operator UnsignedInt() const { return value; }
};
在我开始实现这些模板成员函数之前,一切都很顺利——当编译器看到时
template<typename UnsignedInt>
template<typename F>
void binangle<UnsignedInt>::set_from_radians(F rad) {
...
它抛出
...
/home/sipan/src/vgit/signals/tests/../include/binangles_impl.hpp:23:51: error: invalid use of incomplete type ‘class signals::binangle<UnsignedInt>’
23 | void binangle<UnsignedInt>::set_from_radians(F rad) {
|
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 部分定义/别名模板模板参数
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- #为""定义宏;静态";针对不同的上下文
- 如何确保C++函数在定义之前声明(如override关键字)
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在命名空间中定义函数还是限定函数
- 此代码是否违反一个定义规则
- 编译C++时未定义的引用
- 不同翻译单元中不可重载的非内联函数定义
- 为什么在定义函数之前先声明它
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- vscode g++链路故障:体系结构x86_64的未定义符号
- 如何定义一个纯抽象基类