C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 为什么g从具有转换运算符和不可访问的函数调用运算符的类型的std :: function <>初始化失败?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
代码在g 4.9及更高版本(包括从svn current构建时)失败,但是使用clang和microsofts编译器(来自VS2015)编译时没有警告.
#include <functional>

struct A {
  void operator()() const {}
};
struct B {
  void operator()() const {}
};
struct C : private A,private B
{
  operator std::function<void()>() const { return nullptr; }
};

int main()
{
  std::function<void()> f{C{}};
}

由于operator()在struct C中不明确,main()中f的构造失败.

为什么g认为这是模棱两可的? C中的函数调用操作符是私有继承的,不可访问.
向struct C添加一个私有或显式删除的void operator()()const会使代码编译并按预期使用转换运算符.为什么这些无法访问的操作符在无法访问的继承操作符时不会出现问题?

解决方法

构造函数:template< class F>功能(F f);

C 11:

C 14:

在C 11中,此构造函数模板比​​涉及std :: function移动构造函数用户定义的转换运算符的转换序列更好地匹配.因此,重载决策选择构造函数模板,然后由于f不可调用而无法编译.

在C 14中,构造函数模板会发生替换失败,因为f不可调用.因此构造函数模板不参与重载解析,最好的剩余匹配是涉及std :: function移动构造函数用户定义的转换运算符的转换序列,因此使用它.

Clang以C 11和C 14模式编译您的测试用例. GCC在C 11和C 14模式下拒绝您的测试用例.这是另一个在GCC中演示相同问题的测试用例:

#include <type_Traits>

struct A {
  void operator()() const {}
};
struct B {
  void operator()() const {}
};
struct C : A,B {};

template <typename F,typename = std::result_of_t<F&()>>
void test(int) {}

template <typename F>
void test(doublE) {}

int main() {
  test<C>(42);
}

test(int)不应该参与重载决策,因为Std :: result_of_t< F&()>应该是替换失败,所以应该调用test(doublE).但是,此代码无法在GCC中编译.

这是在您的测试用例中看到的相同问题,因为这与用于在libstdc中的std :: function的构造函数模板中实现SFINAE的机制相同.

大佬总结

以上是大佬教程为你收集整理的c – 为什么g从具有转换运算符和不可访问的函数调用运算符的类型的std :: function <>初始化失败?全部内容,希望文章能够帮你解决c – 为什么g从具有转换运算符和不可访问的函数调用运算符的类型的std :: function <>初始化失败?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。