我有一个下面的例子(布尔类型过于安全):
#include <cstdlib>
struct boolean_type
{
explicit
boolean_type(bool _value)
: value_(_value)
{ ; }
explicit
operator bool () const
{
return value_;
}
private :
bool value_;
};
struct A
{
A(int const _i)
: i_(_i)
{ ; }
boolean_type operator == (A const & _other) const
{
return (i_ == _other.i_);
}
private :
int i_;
};
bool t()
{
return A(0) == A(0);
}
int main()
{
return EXIT_SUCCESS;
}
众所周知,这样的代码包含一个错误:“无法转换’((int)((const A*)this)-
我想说:
由于指定的障碍,我不能简单地将bool
的所有条目替换为我的用户代码中的超级安全的boolean_type
(这是mocked-对象),因为,例如,在的返回语句中,提升::变体::操作符==
使用了上述构造,将其视为隐式转换。类似的障碍并不唯一。
为什么在这两种情况下都没有显式转换?
因为如果您想要显式转换,那么程序员就有责任显式化。
在这种情况下,如果您允许隐式转换,那么隐式转换将起作用。但当您将运算符bool
和布尔类型::布尔类型
标记为显式
时,不允许使用它们。
为什么是含蓄的?
因为你没有写转换。你必须:
boolean_type operator == (A const & _other) const
{
return boolean_type (i_ == _other.i_);
}
...以及:
bool t()
{
return (bool) (A(0) == A(0));
}
但是这里有什么风险呢?
你告诉我们<代码>显式专门用来告诉编译器,允许进行某些隐式转换可能存在风险。因此,当您将这些函数标记为显式时,您对编译器说:
好吧,如果你允许从bool到boolean_操作符的隐式转换,或者反之亦然,可能会发生不好的事情。所以不要允许这些隐式转换。
你没有告诉编译器(或我们)为什么那些隐式转换是危险的。你只是说它们是。
你有两个隐式转换。一个在这里:
return (i_ == _other.i_);
另一个在这里:
return A(0) == A(0);
这些是隐式的,因为您没有显式地告诉编译器您想要将比较的结果分别转换为boolean_type
和bool
。这些隐式转换是不允许的,因为您使boolean_type
显式
的构造函数和转换运算符-这就是显式
关键字的全部意义。
你需要做:
return static_cast<boolean_type>(i_ == _other.i_);
以及:
return static_cast<bool>(A(0) == A(0));
将转换为bool
显式的典型原因是,转换可能会在您不打算使用它的情况下使用。例如,如果您有名为b1
和b2
的对象,并且具有非显式的
转换,则可以执行以下操作:
b1 > 0
b1 == b2
这些可能不是布尔转换运算符的预期用途。
我有下面的课:
但是,如果删除转换构造函数“fraction(int nn):nom(nn),den(1){}”或转换运算符“operator double()const{return double(nom)/den;}”,程序运行良好。 我想把分数转换成分数和分数。我可以做什么来既有转换,又有程序编译?
CLANG6、CLANG7和gcc 7.1、7.2和7.3都同意以下代码是有效的C++17代码,但在C++14和C++11下有歧义。MSVC2015和2017也接受它。然而,即使在C++17模式下,GCC-8.1和8.2也拒绝了它: 接受它的编译器选择模板化的显式转换函数。 拒绝它的编译器同意在以下两个方面存在歧义: null 以下是来自(接受代码)的错误:
问题内容: 以Oracle论坛中显示的示例:使用plsql生成excel(xls),我想从查询的数据集中生成一个excel文件。 此处提供的示例有效。但是,我遇到了一些挑战: 我的SQL查询很长,超过了4000个字符的限制。 我想将参数传递给我的查询。 我想以一种非常简单的方式做到这一点,并且不使用Dynamic SQL(如果可能)。 我提出的内容如下: 包装定义: 现在,我的匿名阻止最好是如下所
问题内容: 要从Java 类中创建新对象,通常使用以下语句 我读过new运算符通过在堆中分配内存空间来创建新对象,但是我也读到调用构造函数会创建它。因此,这有点令人困惑。哪一个在创建对象?是 新 运算符还是默认构造函数? 问题答案: 具有与类同名的方法是合法的(尽管令人困惑),消除了任何歧义。指示JVM应该为给定的类和参数列表调用实例初始化方法,并返回已初始化的对象(在初始化方法的第一个(隐藏)参
问题内容: 我发现Java编译对于使用int和float的赋值和自赋值语句具有非预期的行为。 以下代码块说明了该错误。 在自赋值中,编译不会发出错误,但是求和的结果是带有值的int ,并且变量保持值。 在表达式中,编译器会发出一条错误消息 “错误:可能丢失精度” 。 有人可以解释这种行为。 编辑:我已经将此代码块发布在https://compilr.com/cguedes/java-autoass