【问题标题】:error: ‘invoke’ is not a member of ‘std’错误:“调用”不是“标准”的成员
【发布时间】:2017-12-27 07:14:52
【问题描述】:

使用 g++ (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609.

我收到错误提示

slicing.cpp:31:5: error: ‘invoke’ is not a member of ‘std’
slicing.cpp:32:5: error: ‘invoke’ is not a member of ‘std’

编译时

g++ -std=c++17 -O2 -g -Wall -c -o slicing.o slicing.cpp

(与-std=gnu++17相同)代码如下,由Virtual functions and std::function?修改。

我该如何解决这个问题? 我找不到任何有用的信息。

 #include <functional>
 #include <iostream>

 struct base
 {
     base() {std::cout << "base::base" << std::endl;}
     virtual ~base() {std::cout << "base::~base" << std::endl;}
     virtual void operator()() {std::cout << "base::operator()" << std::endl;}
 };

 struct derived1: base
 {
     derived1() {std::cout << "derived1::derived1" << std::endl;}
     virtual ~derived1() {std::cout << "derived1::~derived1" << std::endl;}
     virtual void operator()() {std::cout << "derived1::operator()" << std::endl;}
};

struct derived2: base
{
    derived2() {std::cout << "derived2::derived2" << std::endl;}
    virtual ~derived2() {std::cout << "derived2::~derived2" << std::endl;}
    virtual void operator()() {std::cout << "derived2::operator()" << std::endl;}
};

int main(int argc, char* argv[])
{
    base* ptr1 = new derived1();
    base* ptr2 = new derived2();
    std::function<void()> f1 = *ptr1;
    std::function<void()> f2(*ptr2);
    std::invoke(*ptr1);     // calls derived1::operator()
    std::invoke(*ptr2);     // calls derived2::operator()
    //std::invoke(f1);        // calls base::operator()
    //std::invoke(f2);        // calls base::operator()
    delete ptr1;
    delete ptr2;
    return 0;
}

【问题讨论】:

  • 顺便说一句,如果您想更好地支持最新的 C++ 标准,您需要更新版本的 g++。最新的GCC - 2017 年 12 月即将结束 - 是GCC 7,GCC 8 将在几个月后发布。您的 GCC 5 是在 C++17 标准发布之前开发的。
  • 我在 cppreference 中找到了this
  • @BasileStarynkevitch - 根据gcc.gnu.org/projects/cxx-status.html,“C++17 功能在 GCC 存储库的主干和 GCC 5 及更高版本中作为“主线”GCC 的一部分提供。”
  • 此页面仅介绍核心语言功能。标准库状态在别处描述。并非所有 C++17 库功能都在 gcc5.4 中。如果你想要完整的 C++17 支持,你需要升级编译器。
  • @n.m. - 正确,即使当我阅读gcc.gnu.org/projects/cxx-status.html 时对我来说并不明显。

标签: c++ std


【解决方案1】:

使用GCC 编译器dialect flag -std=c++1z 甚至更好的-std=c++17将您的编译器升级到GCC 7

(ed:您的编译器似乎有点旧,所以它可能无法工作;请注意GCC 5 是在C++17 标准之前发布的

使用 g++(x86_64-win32-seh-rev1,由 MinGW-W64 项目构建)7.2.0

它正确地构建了这个

#include <iostream>
// C++17
#include <functional>

int Func(int a, int b)
{
  return a + b;
}

struct S
{
  void operator() (int a)
  {
    std::cout << a << '\n';
  }
};


int main(/*int argc, char* argv[]*/)
{
  using namespace std;

  std::cout << std::invoke(Func, 10, 20) << '\n'; // 30
  std::invoke(S(), 42); // 42
  std::invoke([]() { std::cout << "hello\n"; }); // hello

  return 0;
}

来源:https://www.viva64.com/en/b/0533/#ID0EOHKO

【讨论】:

  • 重要的不仅仅是-std=c++1z 标志(可以是given-std=c++17,但主要是GCC 7 版本很重要!
  • 那么请改进你的答案来说明这一点。
  • 选项 -std=c++17 已被使用。升级到 g++-6 (Ubuntu/Linaro 6.3.0-18ubuntu2~16.04) 6.3.0 20170519 工作。见this
猜你喜欢
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
相关资源
最近更新 更多