2

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

I receive the error

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

When compiling with

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

(and the same with -std=gnu++17) code below, modified from Virtual functions and std::function?.

How can I fix this? I could not find any useful information.

 #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;
}
  • BTW, if you want good support of recent C++ standard, you need a newer version of `g++`. The latest [GCC](http://gcc.gnu.org/) -near end of December 2017- is [GCC 7](https://gcc.gnu.org/gcc-7/) and GCC 8 will be released in a few months. Your GCC 5 was developed before the C++17 standard was published. – Basile Starynkevitch Dec 27 '17 at 08:19
  • I had found [this](http://en.cppreference.com/w/cpp/utility/functional/invoke) in cppreference. – sancho.s ReinstateMonicaCellio Dec 27 '17 at 08:21
  • @BasileStarynkevitch - According to https://gcc.gnu.org/projects/cxx-status.html, "C++17 features are available as part of "mainline" GCC in the trunk of GCC's repository and in GCC 5 and later." – sancho.s ReinstateMonicaCellio Dec 27 '17 at 08:22
  • This page is about core language features only. The standard library status is described elsewhere. Not all of the C++17 library features are in gcc5.4. If you want full C++17 support you need to upgrade the compiler. – n. m. could be an AI Dec 27 '17 at 08:43
  • @n.m. - Correct, even if it was not obvious for me when I read http://gcc.gnu.org/projects/cxx-status.html . – sancho.s ReinstateMonicaCellio Dec 27 '17 at 08:46

1 Answers1

3

Use the GCC compiler dialect flag -std=c++1z or even better -std=c++17 and upgrade your compiler to GCC 7.

(ed: your compiler seems a bit old so it may not work; notice that GCC 5 was released before the C++17 standard)

With g++ (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 7.2.0

it builds this correctly

#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;
}

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

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
AndersK
  • 35,813
  • 6
  • 60
  • 86
  • It is not only the `-std=c++1z` flag (which can be [given](https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html) as `-std=c++17` but mostly the [GCC 7](https://gcc.gnu.org/gcc-7/) version which matters! – Basile Starynkevitch Dec 27 '17 at 08:22
  • Then please improve your answer to tell that. – Basile Starynkevitch Dec 27 '17 at 08:24
  • Option `-std=c++17` was already used. Having upgraded to g++-6 (Ubuntu/Linaro 6.3.0-18ubuntu2~16.04) 6.3.0 20170519 worked. See [this](https://stackoverflow.com/questions/47987952/error-invoke-is-not-a-member-of-std?noredirect=1#comment82946463_47987952) – sancho.s ReinstateMonicaCellio Dec 27 '17 at 08:47