防止来自布尔值的隐式对象构造
Prevent implict object construction from bool?
我有一个类,X
,它有以下构造函数:
class X{
X(int64_t, int16_t, bool, int8_t);
X(int64_t, int16_t, bool);
X(double);
X(double, FT);
explicit X(const string&);
X(const string&, Y);
};
问题是编译器曾经创建了一个只传递布尔值的 X 对象(假设是双构造函数允许这样做?(并且它导致了问题。
为了防止这种情况,我显式地将 bool 构造函数删除了它:
explicit X(bool) = delete;
但现在我收到编译器错误:
EXPECT_EQUALS(X("9.8901099"), a/b);
EXPECT_EQUALS(X{"56267"}, x);
X x{"-56267E-1"};
X b("5");
编译器说我已经使用了已删除的函数explicit X(bool) = delete
如何防止从布尔值创建 X 的对象?
是因为bool
比std::string
更适合const char[]
。当您没有接受bool
的 ctor 时,则选择std::string
。当您有一个带bool
的 ctor 时,将选择此重载。只有它被删除,所以调用它是非法的。
让我们看看一个简单的免费重载函数的这种行为:
auto foo(int) { cout << "foo int" << endl; }
auto foo(std::string const &) { cout << "foo string" << endl; }
auto main() -> int {
foo(3); // int
foo("Asdf"); // std::string
}
添加bool
重载时:
auto foo(int) { cout << "foo int" << endl; }
auto foo(std::string const &) { cout << "foo string" << endl; }
auto foo(bool) { cout << "foo bool" << endl; }
auto main() -> int {
foo(3); // int
foo("Asdf"); // bool (also warning implicit conversion turn string literal into bool)
}
解决方案是添加char const *
重载:
auto foo(int) { cout << "foo int" << endl; }
auto foo(std::string const &) { cout << "foo string" << endl; }
auto foo(char const *s) {
cout << "foo char const *" << endl;
// possibly:
return foo(std::string{s});
}
auto foo(bool) = delete;
auto main() -> int {
foo(3); // int
foo("Asdf"); // char const *
foo(true); // error
}
由于某些旧代码使用并返回char *
而不是char const *
因此您可能还需要添加char *
重载。
首先,您需要了解显式删除 bool 构造函数会发生什么。它在重载选择中变得可用,当它是最佳匹配时,它会被使用,然后给出编译器错误,因为它被删除了。
这与你不定义它时不同,因为你确实可以通过隐式转换加后跟类X
的(不同的(构造函数来"阻止"布尔值的转换,因为它是布尔值的最佳匹配,所以隐式转换停止到此。
考虑类的用法
X x("abc");
如果没有已删除的 bool
构造函数,这将选择 X(const string&)
。
但是,对于已删除的bool
构造函数,这将选择explicit X(bool)
,该也会被删除,因此会给出编译器错误。正如 Kerrek SB 所说,解决这个问题的解决方案是也为 const char *
定义一个构造函数。
实际上,如果您不删除bool
构造函数,则以下内容将选择double
X x(true);
通过首先转换为int
,然后转换为double
。
因此,您可以选择删除或不删除的解决方案,但您需要了解后果和要求。如果删除它,则需要提供一个const char *
构造函数。如果你不删除它,那么你需要接受这样一个事实,即bool
可以用来构造你的类的实例。
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 变量定义到C++布尔值转换
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 重载更少,则运算符返回相反的布尔值
- 将此布尔值传递给此函数的最有效方法是什么?
- 如何设置 c++ 类的布尔值?
- 使用 MAKEWORD / MAKEWPARAM 使用布尔值而不是布尔值
- 将 10 个线程与原子布尔值同步
- 创建类似于布尔值的变量类型
- 静态分配对象的值初始化
- 布尔值向量的基于范围 for 循环
- fstream / ifstream / ofstream 对象如何转换为布尔值
- Android :需要在 c++ NDK 中创建共享首选项对象并存储一些布尔值
- 布尔值与虚空*在同一对象上投射
- 在一个作用域中推送五个对象指针,然后检查对象的布尔值是否为 false,会给出错误
- 基于C 中布尔值向量中的向量中选择对象
- 使用布尔值数组"表达式必须具有指向对象类型的指针"错误C++
- C++ 基于成员布尔值对向量中的对象进行排序
- 防止来自布尔值的隐式对象构造
- 哪个操作符重载被用于ifstream对象求值为布尔值