Hol*_*olt 18 c++ function-object std-function return-type-deduction c++14
以下片段:
#include <functional>
struct X {
X(std::function<double(double)> fn); // (1)
X(double, double); // (2)
template <class T>
auto operator()(T const& t) const { // (3)
return t.foo();
}
};
int main() {
double a, b;
auto x = X(a, b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
... 当使用- 在OSX和godbolt.org上测试时,无法使用clang(4.0.1)和g++(6.3,7.2)-std=c++14进行编译.
但如果符合以下情况,它编译没有问
(1);double)(3);-> decltype(t.foo()))(3);-std=c++1z(感谢@bolov).也许有一些明显我在这里失踪的东西......这段代码有什么问题吗?这是一个错误吗?
Sto*_*ica 21
你是复制初始化x.X由于以下原因,这是一个棘手的类型:
它可以从任何可以使用double参数调用的可调用对象构造.并且其返回类型可以转换为double.
它本身是一个可调用的对象,可以使用double参数调用.但是返回类型需要推断.
有一个编译器生成的复制构造函数X.
我希望,模糊性在这里开始变得明显.需要重载解决方案.
当你删除第一个c'tor时,它以明显的方式消除了歧义.有趣的情况是函数调用操作符.
你看,std::function如果参数的参数之间和返回类型之间的转换是可能的,那么只能通过它传递的可调用来构造(模板化的c'tor只会参与重载决策).这都是在未评估的上下文中完成的,因此模板化的函数调用操作符不会使用,因此不会实例化.
当返回类型是占位符类型时,std::function如果应该构造它,则c'tor不能轻易解决.在重载解析期间编译失败,即使它成功了,X也会选择复制文件.
正如@VTT在评论中所建议的那样,标记接受std::function明确的c'tor也将解决歧义.所有这些都是因为编译器根本不必对隐式转换序列进行排序.
| 归档时间: |
|
| 查看次数: |
625 次 |
| 最近记录: |