Visual Studio 2013'显式'关键字错误?

时间:2013-12-10 15:16:30

标签: c++ visual-studio-2013 explicit-conversion

考虑以下计划:

#include <iostream>

class A
{
public:
  A( ) { std::cout << "A()\n"; }

  A( A& ) = delete;

  A( int i ) { std::cout << "A( " << i << " )\n"; }

  explicit operator int( ) { std::cout << "operator int()\n"; return 42; }
};

template< typename T = A > void f( T a = A() ) {}

int main( void )
{
  f();
  return 0;
}

Visual Studio 2013编译此代码并使用输出

运行
A()
operator int()
A( 42 )

这是编译器错误吗?看起来VS编译器在此上下文中没有注意到'explicit'关键字。根据我的理解,VS 2013错误地将operator int()与A(int)结合使用,将'copy-construct'A排序为f的默认参数。

两者都添加

A a;
A a1( a );

到main并将f声明为

void f( A a = A() ) {}

没有编译,VS抱怨A(A&amp;)被删除,这似乎是正确的行为。只有在函数模板default参数的上下文中,运算符int()和A(int)的组合似乎可以替代A(A&amp;)。

g ++ 4.7.3不编译代码并抱怨:

main.cpp: In function ‘int main()’:
main.cpp:21:7: error: no matching function for call to ‘A::A(A)’
main.cpp:21:7: note: candidates are:
main.cpp:10:3: note: A::A(int)
main.cpp:10:3: note:   no known conversion for argument 1 from ‘A’ to ‘int’
main.cpp:6:3: note: A::A()
main.cpp:6:3: note:   candidate expects 0 arguments, 1 provided

删除'explicit'使得g ++编译代码并且输出相同。

2 个答案:

答案 0 :(得分:6)

这绝对是Visual C ++中的一个错误。根据标准:

  

12.3.2转换函数[class.conv.fct]

     

2 - 转换函数可以是显式的(7.1.2),在这种情况下它是   仅被视为用户定义的直接初始化转换   (8.5)在某些情况下(13.3.1.4,13.3.1.5,13.3.1.6)。

并且您的示例中没有直接初始化。

其他C ++编译器(例如GCC和Clang)在这种情况下报告错误。

答案 1 :(得分:2)