【问题标题】:Preventing implicit cast of numerical types in constructor in C++防止在 C++ 中的构造函数中隐式转换数字类型
【发布时间】:2010-02-19 08:54:54
【问题描述】:

我有一个形式的构造函数:

MyClass(int a, int b, int c);

它会被这样的代码调用:

MyClass my_object(4.0, 3.14, 0.002);

我想阻止这种从 double 到 int 的自动转换,或者至少在编译时得到警告。

“显式”关键字似乎在这些情况下不起作用,对吧?

【问题讨论】:

  • 演员阵容根据定义是明确的。您的意思是标题中的“隐式转换”。

标签: c++ casting constructor implicit


【解决方案1】:

你的编译器是什么?在 gcc 下,您可以使用 -Wconversion 警告您这些类型的转换。

【讨论】:

  • 我使用 gcc,-Wconversion 确实有效!我以为 -Wall 会包含这个,但显然它没有!非常感谢!
  • -Wall 缺少很多东西,甚至 -Wall -Wextra 都没有。我希望有一个开关来真正启用所有警告,然后逐个禁用引起问题的警告。
  • 就个人而言,我使用“-Wall -Wextra -pedantic -Wformat=2 -Wstrict-overflow=3 -Werror”进行编译。我在开发过程中添加了“-Wno-unused”,因为我经常有一些我还没有准备好使用的东西,但我想要它们,因为我知道我会需要它们。
【解决方案2】:

像这样声明一个私有构造函数:

private:
template <class P1, class P2, class P3>
MyClass(P1,P2,P3);

对于使用 3 个不全是 int 的参数的任何构造,这将导致编译时错误,并且它是可移植的。

【讨论】:

  • 这很聪明。 :-) 警告解决方案更简洁,但您的解决方案适用于任何符合要求的编译器。 :-) 不幸的是,它不能防止类直接构造自身的实例。您必须等到链接时间才能赶上这些。
  • @Omnifarious:使用 C++0x 你只需用= delete; 标记这个重载否则,如果你担心内部滥用,你可以提供一个编译失败的实现(例如,因为静态断言)。
  • 更聪明:添加第二个重载template &lt;class P1, class P2, class P3&gt; MyClass(P1,P2,P3, P3* dummy = 0);。两个模板之间的重载分辨率将是模棱两可的,但如果两者都比MyClass(int,int,int)更差,这无关紧要@
  • @visitor:我相信= delete; 只能用于删除编译器会自动声明和定义的函数。
  • @Omnifarious:消除不必要的转换似乎是= delete 的一种预期用途。请参阅 C++0x 常见问题解答:www2.research.att.com/~bs/C++0xFAQ.html#default
【解决方案3】:

声明一个私有的MyClass(double a, double b, double c) 构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2013-11-02
    相关资源
    最近更新 更多