【问题标题】:c++ explicit multi-arg constructor ambiguityc++ 显式多参数构造函数歧义
【发布时间】:2017-12-31 01:02:12
【问题描述】:

我现在正在编写的一些代码中遇到了意外问题,我不确定哪个编译器是正确的。

我们有一个采用const char*, const char* 的多参数构造函数,但它是显式声明的:

constexpr explicit Wrapper(const char* a, const char* b)  : pair(a,b){}

然后我们有一个接受Wrapper 的函数和一个接受std::pair<const char*, const char*> 的重载

void q(Wrapper w);
void q(std::pair<const char *, const char *> w);

然后我们有这样的代码,我希望将其称为第二个重载:

q({"a", "b"});

这在 clang 上编译得很好,但在 GCC 和 MSVC 上都无法编译。我一直在尝试在标准中寻找任何提及显式多参数构造函数的内容,如果有任何内容提及这种歧义,但我还没有找到相关文本。我只是想知道哪种行为是正确的,哪种行为是错误的?

神螺栓链接:https://godbolt.org/g/2aYUov

【问题讨论】:

  • 我认为explicit 在这里不算,因为它是一个带有两个参数的构造函数,而不是一个带有一对参数的构造函数。
  • @nefas 根据this other stackoverflow post (stackoverflow.com/questions/1118680/…) 它应该计入c++11及更高版本
  • @nefas 这就是我所期望的(就像它在 clang 中所做的那样)
  • 你用的是哪个版本的 GCC?
  • @PasserBy 这是一个 c++11 功能。我出于习惯写了 -std=c++14 。改成c++11的结果是一样的

标签: c++ c++11


【解决方案1】:

使用您提供的 Wrapper 构造函数,g++ 7.1.1 出现以下错误:

main.cpp: In function ‘int main()’:
main.cpp:29:25: error: converting to ‘Wrapper’ from initializer list would use explicit constructor ‘constexpr Wrapper::Wrapper(const char*, const char*)’
     Wrapper w({"a", "b"});
                         ^

因此,在手动触发转换时,似乎很好地考虑了 Wrapper 构造函数上的显式关键字。

但是,调用 q 的错误似乎表明重载解决方案忽略了显式关键字:

main.cpp:34:17: error: call of overloaded ‘q(<brace-enclosed initializer list>)’ is ambiguous
     q({"a", "b"});
                 ^
main.cpp:16:6: note: candidate: void q(Wrapper)
 void q(Wrapper w)
      ^
main.cpp:21:6: note: candidate: void q(std::pair<const char*, const char*>)
 void q(std::pair<const char *, const char *> w)
      ^

这可能是 g++ 中的错误,需要通过其他来源进行验证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    • 2014-01-13
    • 2013-12-13
    • 2010-09-15
    • 2010-11-10
    相关资源
    最近更新 更多