Overload class member function marked const - c++

I am having trouble overloading class member functions that are marked const, while there is no problem when the functions are not marked const. Also the overload itself works fine in pure C++.
The following fails
#include <vector>
#include <pybind11/pybind11.h>
class Foo
{
public:
Foo(){};
std::vector<double> bar(const std::vector<double> &a) const
{
return a;
}
std::vector<int> bar(const std::vector<int> &a) const
{
return a;
}
};
namespace py = pybind11;
PYBIND11_MODULE(example,m)
{
py::class_<Foo>(m, "Foo")
.def("bar", py::overload_cast<const std::vector<double>&>(&Foo::bar));
}
Compiled using:
clang++ -O3 -shared -std=c++14 `python3-config --cflags --ldflags --libs` example.cpp -o example.so -fPIC
Gives error:
...
no matching function for call to object of type 'const detail::overload_cast_impl<const vector<double, allocator<double> > &>'
.def("bar", py::overload_cast<const std::vector<double>&>(&Foo::bar));
...
Whereas the code works when I remove the const mark of the functions.
How should I perform this overload?

There is a special tag for const overloaded methods.
namespace py = pybind11;
PYBIND11_MODULE(example,m)
{
py::class_<Foo>(m, "Foo")
.def("bar", py::overload_cast<const std::vector<double>&>(&Foo::bar, py::const_));
}

Related

Symbol not found in debugger only, when having templated template argument

Given the following code as test.cpp,
Building using clang++ -c test.cpp -o test.o -g; clang++ test.o -g -all_load, setting breakpoint at return a.getValue(); and attempting to p a.getValue() from lldb:
Running llvm 3.8.0 on unix - works perfectly
Running xcode or llvm 8.1.0 on OSX - I get the following error:
error: Couldn't lookup symbols:
__ZNK4Test7MyClassILi2ELi3EE8getValueEv
Two interesting facts:
If I remove the last template argument - all works well
If I build directly without going through the .o file (clang++ test.cpp) = all goes well
Anyone has a clue what is going on, and how can it be fixed?
namespace Test{
template<class T>
class BLA{
public:
T getBlaValue() const{return 3;}
};
template <int N1, int N2, template<class T>class Impl = BLA>
class MyClass {
private:
public:
__attribute__((used))
int getValue() const
{
return 3;
}
};
}
int main()
{
Test::MyClass<2, 3> a;
return a.getValue();
}

How to pass lambda to a lambda?

I have not managed to find why this code does not
work:
#include <iostream>
#include <functional>
using namespace std;
int main()
{
auto xClosure = [](const function<void(int&)>& myFunction) {
myFunction(10);};
xClosure([]
(int& number) -> void
{cout<<number<<endl;
});
return 0;
}
It returns:
g++ test.cc -o test -std=c++14
test.cc:9:5: error: no matching function for call to object of type 'const function<void
(int &)>'
This has nothing to do with lambdas:
void test(const function<void(int&)>& myFunction) {
myFunction(10);
}
this fails to compile for the same reason; you cannot bind the literal 10 to an int&.
Maybe you meant
const function<void(int)>& myFunction
doing so and also modifying the signature of your lambda should make your code compile.

boost move compile error

I'm trying to implement the move constructor outside the class body, but it won't compile correctly
#include <boost/move/move.hpp>
class Test
{
BOOST_COPYABLE_AND_MOVABLE(Test)
public:
Test() {}
Test(const Test & other) { }
Test(BOOST_RV_REF(Test) other);
Test & operator=(BOOST_COPY_ASSIGN_REF(Test) other) { return *this; }
Test & operator=(BOOST_RV_REF(Test) other) { return *this; }
};
Test::Test(BOOST_RV_REF(Test) other) { }
I compiled this code with g++, my g++ version is 4.4.7
$ g++ -c test.cpp
test.cpp:15: error: prototype for 'Test::Test(boost::rv<Test>&)' does not match any in class 'Test'
test.cpp:9: error: candidates are: Test::Test(boost:rv<Test>&)
test.cpp:8: error: Test::Test(const Test&)
test.cpp:7: error: Test::Test()
It also failed with g++ 5.4.0 – flyzero
Must be your boost version.
It works fine with g++ 5.4.1 and Boost 1.64. If not, check the preprocessor output for any include/macro mishaps.
In Linux, ::boost::rv is declared with may_alias attribute. My code compile correctly after removing the may_alias attribute.
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
template <class T>
class rv
: public ::boost::move_detail::if_c
< ::boost::move_detail::is_class<T>::value
, T
, ::boost::move_detail::nat
>::type
{
rv();
~rv() throw();
rv(rv const&);
void operator=(rv const&);
} BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;

Returning a map of structs from within a class (where the struct definition is within the class): compile error

I have a class, and within that class I define a struct. The struct has overloaded comparison operators so that it can be used with a map (with an int as the key).
Prior to messing with classes, I had the struct defined in a .cc file, and that file also contained a function which returned a map of this struct. It worked.
Now I want to have the struct defined in the class header, and the class should have a function which returns a map of structs.
Here is a simplified version of my code, which compiles with the same error as the full version. I don't understand the error, and would appreciate any help!
Cheers.
myclass.h:
#include <map>
class myclass {
public:
struct mystruct {
int i;
mystruct();
mystruct(int j);
bool operator==(const mystruct& rhs);
bool operator>(const mystruct& rhs);
bool operator<(const mystruct& rhs);
};
::std::map<int,mystruct> getStructMap();
};
myclass.cc:
#include <map>
#include "myclass.h"
myclass::mystruct::mystruct(int j) : i(j) {};
myclass::mystruct::mystruct() : i(-1) {};
bool ::myclass::mystruct::operator==(const ::myclass::mystruct& rhs) {return i==rhs.i; }
bool ::myclass::mystruct::operator>(const ::myclass::mystruct& rhs) {return i>rhs.i; }
bool ::myclass::mystruct::operator<(const ::myclass::mystruct& rhs) {return i<rhs.i; }
::std::map<int,::myclass::mystruct> ::myclass::getStructMap() {
::std::map<int,::myclass::mystruct> structMap;
for (int i=0;i<5;i++) structMap[i]=::myclass::mystruct(i);
return structMap;
}
myprogram.cc:
#include <iostream>
#include <map>
#include "myclass.h"
int main() {
myclass myobj;
::std::map<int,::myclass::mystruct> mymap;
mymap=myobj.getStructMap();
}
compile error:
> g++ -o myprogram myprogram.cc myclass.cc
myclass.cc:12: error: ‘class std::map<int, myclass::mystruct, std::less<int>,std::allocator<std::pair<const int, myclass::mystruct> > >::myclass’ has not been declared
myclass.cc:12: error: ISO C++ forbids declaration of ‘getStructMap’ with no type
myclass.cc: In function ‘int getStructMap()’:
myclass.cc:15: error: cannot convert ‘std::map<int, myclass::mystruct, std::less<int>, std::allocator<std::pair<const int, myclass::mystruct> > >’ to ‘int’ in return
Currently your code in parsed as
/*missing type*/ ::std::map<int,::myclass::mystruct>::myclass::getStructMap()
Thus, first error, map doesn't have myclass member (or subclasses, method, typedef, ...)
then the second error : no return type (so assuming int and thus the conversion error).
So to solve that, in myclass.cc, you may remove extra :: as follow:
::std::map<int,::myclass::mystruct> myclass::getStructMap() {
or add extra parenthesis:
::std::map<int,::myclass::mystruct> (::myclass::getStructMap()) {

"Is not a direct base of " gcc 4.5.2 compiler error

I have this code
#include <vector>
#include <array>
template <typename T>
struct Vertice
{
T elements_[4];
Vertice(const T & x, const T & y, const T & z)
{
elements_[0] = x;
elements_[1] = y;
elements_[2] = z;
elements_[3] = T(1);
}
Vertice() : Vertice(T(0), T(0), T(0)) {}
};
typedef Vertice<float> VerticeF;
std::array<VerticeF, 5> v2;
and returns following error when compiling with gcc 4.5.2:
$ g++ -o tutorial tutorial.cpp -std=gnu++0x
tutorial.cpp: In constructor ‘Vertice<T>::Vertice() [with T = float]’:
/usr/include/c++/4.5/tr1_impl/array:50:5: instantiated from here
tutorial.cpp:28:41: error: type ‘Vertice<float>’ is not a direct base of ‘Vertice<float>
However, if I don't use constructor delegation, works properly.
Why?
GCC 4.5 does not support constructor delegation; you need to use GCC 4.7; see http://gcc.gnu.org/projects/cxx0x.html.