【问题标题】:Clang typecasting using C++11 has ambiguous compiler behaviour使用 C++11 的 Clang 类型转换具有模棱两可的编译器行为
【发布时间】:2012-10-24 18:33:08
【问题描述】:

考虑以下代码:

#include<iostream>
#include<vector>
using namespace std;
class Foo {
public:
  template< typename T> 
  operator vector< T >() const {
    return vector< T >();
  }

  template< typename T> 
  operator T() const {
    return T();
  }
};

int main () {
  Foo b;
  vector< int >  q = b;
  q = b;
}

使用 Clang 或 g++ 使用以下两个命令之一进行编译:

g++ test.cpp
clang++ test.cpp

但是,启用 C++11 功能失败:

g++ --std=c++0x test.cpp
clang++ --std=c++11 test.cpp

错误信息如下:

test.cpp:20:5: error: use of overloaded operator '=' is ambiguous (with operand types 'vector<int>' and 'Foo')
  q = b;
  ~ ^ ~
/usr/include/c++/4.6/bits/stl_vector.h:373:7: note: candidate function
      operator=(vector&& __x)
      ^
/usr/include/c++/4.6/bits/stl_vector.h:362:7: note: candidate function
      operator=(const vector& __x);
      ^
/usr/include/c++/4.6/bits/stl_vector.h:394:7: note: candidate function
      operator=(initializer_list<value_type> __l)
      ^
1 error generated.

我不清楚为什么它在没有 C++11 的情况下也能工作,而它却失败了。 Moveover,注意那行

vector< int >  q = b; // In the main function, line 19

在 main 函数中不会导致错误。谁能解释为什么它不起作用,以及如何使它与 C++11 一起工作?

【问题讨论】:

  • 看来这可能是 LLVM 3.0 中的一个错误。使用 LLVM 3.1 编译它可以工作。
  • @Xeo,就这样吧。我也确信这是错误。但是,它似乎仍然是 Clang 3.1 中的一部分,因为 q = vector(b);在 q = b 有效时失败。
  • 别在意我的最后一条评论,我弄混了一些东西。现在重新考虑。

标签: c++ templates c++11 clang


【解决方案1】:

这里没有编译器错误。您的代码在 C++11 中被破坏,因为 C++11 为赋值运算符添加了更多转换构造函数和更多重载。

当您创建一个可以转换为绝对任何东西的类型(使用模板化转换)时,这是您面临的风险。 Foo 很乐意将自己转换为 initializer_list&lt;int&gt; 和 vector&lt;int&gt;。

原因

vector<int> q = b;

在 Clang 3.1 中工作,而

vector<int> q(b);

失败,是第一个是copy-initialization,它需要隐式转换为vector&lt;int&gt;,然后是复制构造函数调用,而第二个是直接初始化,它执行显式转换。隐式转换的候选集更小,因为标记为 explicit 的构造函数已被移除,从而解决了歧义。

Clang 3.0 和 3.1 之间的差异可能是库合规性修复,它将其他构造函数标记为 explicit,而不是对编译器行为的更改。

【讨论】:

  • 你完全正确。该行为是由 C++11 中引入的初始化列表引起的。为了克服这个问题,添加: template operator std::initializer_list() = delete;这会禁用到 initializer_list 的转换。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 2014-05-12
  • 1970-01-01
  • 2017-12-16
  • 2015-11-19
相关资源
最近更新 更多