有没有办法避免无意中将非布尔参数传递给布尔参数
Is there a way to avoid inadvertently passing a non-boolean argument to a boolean parameter?
我今天遇到了一个C++类型安全问题,我想知道是否有一种好方法可以让编译器在编译时检测到这个问题。 请考虑以下示例代码:
class Bar
{
public:
void Foo(bool arg1 = false, int arg2 = 10, int arg3 = 20)
{
[...]
}
};
int main(int argc, char ** argv)
{
int x = 40, y = 50;
Bar b;
b.Foo(); // correct usage
b.Foo(true, x, y); // correct usage
b.Foo(x, y); // problem: compiles but won't do what the caller expects
}
如对 b.Foo() 的最终调用所示,问题在于很容易忘记提供第一个参数,在这种情况下,编译器无法捕获错误。
如果我能让编译器说"错误,非布尔值被提供给布尔参数"之类的话,那就太好了。 这将迫使开发人员检查代码,如果他真的想传入x作为布尔值,他必须传入(x!=0)。
这似乎是使用"显式"关键字的好地方,但 AFAICT 该关键字不适用于函数参数。
(我意识到可以通过不为参数提供默认值来避免此类问题,但默认值可能非常方便)
您可以提供已删除的重载:
class Bar
{
public:
void Foo(bool arg1 = false, int arg2 = 10, int arg3 = 20)
{
[...]
}
template <typename T>
void Foo(T&&, int = 10, int = 20) = delete;
};
由于模板方法将与非布尔参数完全匹配。
函数重载可以捕获它
public: void Foo(bool arg1 = false, int arg2 = 10, int arg3 = 20);
private: void Foo(int&, ...); // can't omit leading arguments, dummy!
或者在 C++11 及更高版本中,使用 = delete
(不过,一些所谓的 C++11 编译器尚不支持此功能)
正如您所指出的explicit bool
在这种情况下不起作用 - 但我们可以设法使Explicit<bool>
工作,这看起来几乎完全相同。
首先,一些SFINAE特质魔法有助于提供一个类,该类具有仅适用于实际bool
的构造函数:
#include <type_traits>
template<typename U>
struct Explicit
{
bool value;
template<typename T = U, typename = std::enable_if_t<std::is_same<std::decay_t<T>, U>::value>>
Explicit(T&& value) : value(value) { }
operator U() { return value; }
};
有了这个助手,您可以简单地说:
void Foo(Explicit<bool> arg1 = false, int arg2 = 10, int arg3 = 20) { }
查看成功和失败,并特别注意错误消息:
prog.cpp:22:11:错误:无法将"x"从"int"转换为"显式
您可以尝试将此技巧与模板一起使用:
template <class T>
void foo(T param);
template <>
void foo<bool>(bool param)
{
}
foo(true); // OK
foo(9); // Won't c̶o̶m̶p̶i̶l̶e̶ link
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将部分流作为参数传递
- 我正在开发服务器,ip作为参数传递不起作用
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 将参数传递为"const"的奇怪效果
- 如何在 c++ 中将函数作为参数传递?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 将此布尔值传递给此函数的最有效方法是什么?
- 使用引用与指针将数组作为参数传递
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 有没有办法避免无意中将非布尔参数传递给布尔参数
- 返回布尔函数的值,并将指针作为参数传递