有什么方法可以定义"doubling"运算符吗?
Any way to define a "doubling" operator?
我有一个类,它表示一个只能取整数值或半整数值的量,因此它的值在内部存储为值的两倍整数。也就是说:值0.5存储为1,1存储为2,1.5存储为3,等等。让我们用存储的值int TwoA_
将其称为class A
。
这将强制A
值正确地为整数或半整数。由于我经常需要使用它们作为它们的真值,所以我自然地生成了一个转换为double
的运算符,它只返回0.5 * TwoA_
。
然而,我经常需要使用两倍的值。我认为对2 * a
(a
是A
类型的对象(进行编码以直接返回存储在a
中的值TwoA_
会很好。
理想情况下,我想做一个运算符,它只在从左边乘以2
时才这样做。所有其他情况都将由隐式演员阵容覆盖。
在c++中有什么方法可以做到这一点吗?我想到了某种模板化的乘法运算符。
定义的简单解决方案
friend double operator*(int lhs, const A& rhs)
{ return (lhs == 2) ? rhs.TwoA_ : lhs * static_cast<double>(rhs); }
不是我想要的。2 * a
保证是int
(但一般来说an_int * a
不是(,我想返回一个int
这是一个好奇的问题;如果你只想评论"你为什么要这么做?"(或其变体(,请保持沉默。
编辑:我指的是左边的整数文字2
(不是一个测试值是否为2的整数变量(
理解您的问题是,如果您可以重载*
运算符,使其根据其中一个参数的值返回不同的数据类型,简短的答案是:否。
长话短说:没有,但也许是的。
double operator*(const int lhs, const A& rhs);
如果lhs
是否为2
,则该操作员必须在COMPILE TIME上知道,而这一点无法保证。这意味着必须在运行时决定如何处理lhs
是否为2
的情况。但是运算符返回的数据类型必须在编译时已知。。。
double operator*(const some_type_1& lhs, const A& rhs);
int operator*(const some_type_2& lhs, const A& rhs);
这将获得两种不同的返回类型,但只有在编译时了解这些参数类型的情况下。
template<int T>
struct special_number{};
//...
template<>
int operator*(const special_number<2>&, const A& rhs){
return rhs.TwoA_;
}
template<int T>
double operator*(const special_number<T>&, const A& rhs){
return (static_cast<double>(rhs) / 2.0) * T;
}
//usage
int answer1 = special_number<2> * my_a_object;
double answer2 = special_number<3> * my_a_object;
这样就可以了。
struct two_t {
constexpr two_t() {};
template<class T>
constexpr operator T()const{return 2;}
};
constexpr two_t two;
现在:
friend double operator*(two_t lhs, const A& rhs)
{ return rhs.TwoA_; }
friend double operator*(const A& lhs, two_t lhs)
{ return lhs.TwoA_; }
是关于你能做的最好的。
表达式的类型不依赖于值,除非在特殊情况下,常数0
可以转换为指针,并且可能导致不同的重载分辨率。
当作为参数传递给*
时,不能利用这种特殊情况使2
变得特殊。
现在
constexpr std::ptrdiff_t from_digits(std::integer_sequence<char>) {
return 0;
}
constexpr std::ptrdiff_t compile_time_pow( std::ptrdiff_t base, std::size_t exp ) {
return exp ? base * compile_time_pow( base, exp-1 ) : std::ptrdiff_t(1);
}
template<char c0, char...cs>
constexpr std::ptrdiff_t from_digits(std::integer_sequence<char, c0, cs...>) {
return
compile_time_pow(10, sizeof...(cs))*(c0-'0')
+ from_digits( std::integer_sequence<char, cs...>{} );
}
template<char...cs>
constexpr auto operator"" _integer() {
return std::integral_constant<std::ptrdiff_t, from_digits( std::integer_sequence<char, cs...>{} )>{};
}
现在,2_integer
是值为2
的compile_time std::ptrdiff_t
,其值以其类型编码。
因此,2_integer * a
可以被重写以返回与3_integer * a
或2 * a
不同的类型。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 有什么方法可以定义"doubling"运算符吗?