【问题标题】:Unexpected behaviour with overload resolution when using std::initializer_list with a boolean overloaded function将 std::initializer_list 与布尔重载函数一起使用时,重载解析的意外行为
【发布时间】:2015-06-02 09:59:57
【问题描述】:

我正在尝试使用具有不同重载函数的初始化列表,如下面的示例代码所示。看来布尔重载和数组重载与映射重载有着排他的存在主义。

#include <string>
struct Spam
{
    Spam();
    Spam(bool flag);   //(1)
    Spam(const std::initializer_list<std::pair<const std::string, Spam > > &  il); //(2)
    Spam(const std::initializer_list<Spam > & il); //(3)
};
int main()
{
    Spam({ { "1", Spam() }, { "2", Spam() } });
}

这意味着在上面的代码中Spam(bool flag)Spam(const std::initializer_list&lt;Spam &gt; &amp; il) 在使用初始化列表Spam(const std::initializer_list&lt;std::pair&lt;const std::string, Spam &gt; &gt; &amp; il) 的映射版本时不能共存。编译器抱怨

error C2440: '<function-style-cast>' : cannot convert from 'initializer-list' to 'Spam'

这种行为最初是在 VC12 中观察到的,后来在 G++ [See Demo]Clang [See Demo] 中被复制 行为出乎意料。这种奇怪行为的原因是什么以及如何解决?

【问题讨论】:

  • 乍一看,这可能是由于字符串文字的指针转换从 array of 2 const charpointer to const charbool。此转换通过 Spam(bool) ctor 启用转换字符串文字 -> SpamLive demo
  • 在相关的说明中,采用基本类型(如bool)的单参数构造函数默认情况下应该是显式的,因为它们允许这种有趣的转换。这也应该可以防止您的问题。 Live demo

标签: c++ c++11 language-lawyer initializer-list overloading


【解决方案1】:

编译器不知道{"1", Spam()}std::pairSpam

尝试用std::make_pair() 包装它们。

Spam({std::make_pair("1", Spam()),
      std::make_pair("2", Spam())
     });

【讨论】:

    猜你喜欢
    • 2014-09-12
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    相关资源
    最近更新 更多