问题如上,更多详情如下:
我有一堂课Money要处理......好吧,你猜对了.我非常严格,不允许Money和double互动(*),所以下面的代码是没有可能的:
Money m1( 4.50 );
double d = 1.5;
Money m2 = m1 * d; // <-- compiler error
Run Code Online (Sandbox Code Playgroud)
现在我想允许乘Money用int,如"你有6个饼每个$ 4.50的(所以去什么地方找到更便宜的蛋糕)."
class Money
{
Money();
Money( const Money & other );
explicit Money( double d );
...
Money & operator*=( int i );
...
}
inline const Money operator*( const Money & m, int i ) { return Money( m ) *= i; }
inline const Money operator*( int i, const Money & m ) { return Money( m ) *= i; }
Run Code Online (Sandbox Code Playgroud)
这工作正常,但是 ...不幸的是,C++不隐式转换从double到int,如此突然我的第一个代码段编译.我不希望这样.在这种情况下有没有办法防止隐式演员?
谢谢! - 罗宾
(*)原因:我有很多遗留代码处理所有Money相关的东西double,我不希望这些类型混淆,直到一切都运行Money.
编辑:为Money添加构造函数.
编辑:谢谢,大家,谢谢你的答案.几乎所有人都很棒,乐于助人.R. Martinho Fernandes的评论"你能做到inline const Money operator*( const Money & m, double d ) = delete;"实际上是答案(一旦我切换到支持C++ 11的编译器).Kerrek SB提供了一个很好的非C++ 11选择,但我最终使用的实际上是Nicola Musatti的"超载long"方法.这就是为什么我将他的答案标记为"答案"(也因为所有有用的想法都作为对他答案的评论).再次,谢谢!
Ker*_* SB 15
模板加上编译时特征检查怎么样:
#include <type_traits>
// ...
template <typename T>
Money & operator*=(const T & n)
{
static_assert(std::is_integral<T>::value, "Error: can only multiply money by integral amounts!");
// ...
}
Run Code Online (Sandbox Code Playgroud)
您可以为扩充赋值运算符的私有重载添加声明:
private:
Money & operator*=( double i );
Run Code Online (Sandbox Code Playgroud)
我可以想到两种方法来提供这个:
使用重载是C++ 11解决方案.C++ 11 delete 特别为您的案例引入了关键字!
Money& operator*=(int i);
Money& operator*=(float f) = delete;
Money operator*(Money m, int i) { return m*i; }
Money operator*(Money m, float f) = delete;
Money operator*(int i, Money m) { return m*i; }
Money operator*(float f, Money m) = delete;
Run Code Online (Sandbox Code Playgroud)
旧的方式(C++ 03)去了两倍:
private第二个是类方法案例中的安全措施,也是自由方法案例中的唯一方法.令人遗憾的是,它仅在链接时被检测到...并且delete关键字更好;)
使用模板是另一种解决方案 您可以使用std::enable_if或者static_assert:one将从重载集(SFINAE)中删除该函数,而另一个将使实例化失败(编译器错误).
例:
// For enable_if
template <typename T>
std::enable_if<std::is_integral<T>::value, Money&> operator*=(T t);
template <typename T>
std::enable_if<std::is_integral<T>::value, Money> operator*(Money m, T t);
template <typename T>
std::enable_if<std::is_integral<T>::value, Money> operator*(T t, Money m);
Run Code Online (Sandbox Code Playgroud)
这些例子static_assert更自然(它就像常规断言一样).
delete如果你有,我宁愿推荐重载+ .如果不这样做,那么回退到模板案例可能是最好的解决方案,因为它比链接器更容易纠正编译器错误.
| 归档时间: |
|
| 查看次数: |
5684 次 |
| 最近记录: |