具有复杂<double>的功能样式转换的模糊转换

Reb*_*bin 3 c++ lambda g++ clang c++14

我有一个MVE程序,用g ++ - 5.2.0编译和运行,但没有使用clang-602.0.53.该程序尝试将lambda表达式分配给兼容类型的类型别名.

#include<iostream>
#include<complex>

using std::cout;
using std::endl;
using std::complex;
// type alias
using CfDD = complex<double> (*) (double);
// lambda of compatible type
auto theLambda = [] (double _) {return complex<double>({1,0});};

int main()
{   // Show that the lambda is callable:
    cout << theLambda(3.14) << endl;
    // Show that the lambda is assignable to a var of type CfDD
    CfDD cfdd = theLambda;
    cout << cfdd (3.14) << endl;
}
Run Code Online (Sandbox Code Playgroud)

使用g ++ - 5.2.0编译时,此程序有效:

$ g++-5 --version
g++-5 (Homebrew gcc 5.2.0) 5.2.0
   ...
$ g++-5 -std=c++14 main.cpp && ./a.out
(1,0)
(1,0)
Run Code Online (Sandbox Code Playgroud)

但产生一个我不理解的错误,不知道如何修复clang:

$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with- gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
    ...

$ gcc -std=c++14 main.cpp

main.cpp:10:40: error: ambiguous conversion for functional-style cast from 'void' to
  'complex<double>'
auto theLambda = [] (double _) {return complex<double>({1,0});};
                                       ^~~~~~~~~~~~~~~~~~~~~
    ...      candidate is the implicit move constructor
class _LIBCPP_TYPE_VIS_ONLY complex<double>
                            ^
    ...      candidate is the implicit copy constructor
candidate constructor
complex<double>::complex(const complex<float>& __c)
Run Code Online (Sandbox Code Playgroud)

这个错误意味着什么,为什么这个代码不能编译?

Bar*_*rry 6

你写的时候:

return complex<double>({1,0});
Run Code Online (Sandbox Code Playgroud)

我们查看有效的构造函数std::complex<double>并找到:

constexpr complex(double re = 0.0, double im = 0.0); // (1)

constexpr complex( const complex& other ); // (2)

constexpr complex(const complex<float>& other); // (3a)
explicit constexpr complex(const complex<long double>& other); // (3b)
Run Code Online (Sandbox Code Playgroud)

我们用初始化列表构造这个对象.所以(1)不可行,也不是(3b)因为那个构造函数被标记了explicit.另外两个,但是,都是因为两个可行的complex<double>并且complex<float>可以由两个来构造int秒.两者都不比另一个好,这就是为什么clang抱怨"模糊的转换".

最简单的解决方案是删除不必要的{}s:

return complex<double>(1,0);
Run Code Online (Sandbox Code Playgroud)

请注意,您不需要为参数命名_,也不能为其提供名称.