When is the const version called? - constants

I made "T operator[](int i) const" and "T& operator[](int i)" for class A.
(and I also tried it for "const T& operator[](int i) const" and "T& operator[](int i)")
The operator print a value to distinguish which operator is called.
A a;
int k = a[0];
k = a[0];
const int l = a[0];
result : three calls of non-const version.
How can I call const version?
Should I use const class?
There is no chance to call a function that is const version without using const class?

You can use a const reference:
const A& b=a;
k=b[0];
Or a const cast:
k=const_cast<const A&>(a)[0];

Related

SolidJS: Is there a way to pass in an object to the first param of `createResource`

Is there a way to pass in an object to the first param of createResource? For example: I am trying the following and it is not working:
const [val] = createResource(props, req);
I have also tried a few other things including the following:
const [val] = createResource(signal(), req);
const [val] = createResource(["foo","bar"], req);
const [val] = createResource(merged, req);
For the source argument of createResource to be reactive, you need to pass a function that is reading from a signal. Then the createResource will be able to track it and refetch when it changes.
const [data] = createResource(() => ({ ...props }), fetcher);
Here I'm destructuring props object to read all of its properties within the tracking scope of the source function.
Playground demo
Here's a longer explanation for someone like whose unable to grasp the answer in the first go:
You can define two signals:
const [state1, setState1] = createSignal("");
const [state2, setState2] = createSignal("");
You need to create a function that derives the state from those signals:
const derivedState = () => {
console.log('func called')
return {value1: state1(), value2: state2()}
}
You can then use it with your fetcher in createResource:
const [data] = createResource(derivedState, fetcherFunction);
This is what an example signature for the fetcher looks like:
async function fetcherFunction(derivedState: {
value1: string;
value2: string;
}) {
...

pybind with array as class attribute

I want to wrap the following C++ code into python using pybind
class Galaxy {
public:
double x[3];
double v[3];
};
class GalaxyCatalogue {
public:
long n_tracers;
Galaxy *object;
GalaxyCatalogue(long n_tracers);
~GalaxyCatalogue();
};
GalaxyCatalogue::GalaxyCatalogue(long n_tracers) : n_tracers(n_tracers) {
std::cout << "from galaxies " << n_tracers << std::endl;
object = new Galaxy[n_tracers];
std::cout << "has been allocated " << std::endl;
}
GalaxyCatalogue::~GalaxyCatalogue() {
delete[] object;
}
The first problem I have is that Galaxy doesn't have a constructor, so I'm not sure what to do with that. Even if I declare an empty constructor I don't know how to treat the array in a way that I don't get an error when compiling. This is what I've tried:
#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;
class Galaxy {
public:
Galaxy();
double x[3];
};
PYBIND11_MODULE(example, m){
py::class_<Galaxy>(m, "Galaxy")
.def(py::init<>())
.def_readwrite("x", &Galaxy::x);
}
This is how I compile it:
c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` gal.cpp -o example`python3-config --extension-suffix`
and this is the error I get:
In file included from gal.cpp:1:
/home/florpi/.conda/envs/virtualito/include/python3.5m/pybind11/pybind11.h: In instantiation of ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = Galaxy; D = double [3]; Extra = {}; type_ = Galaxy; options = {}]’:
gal.cpp:19:33: required from here
/home/florpi/.conda/envs/virtualito/include/python3.5m/pybind11/pybind11.h:1163:65: error: invalid array assignment
fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));
~~~~~~^~~~~~~
In file included from gal.cpp:1:
/home/florpi/.conda/envs/virtualito/include/python3.5m/pybind11/pybind11.h:64:5: error: ‘pybind11::cpp_function::cpp_function(Func&&, const Extra& ...) [with Func = pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = Galaxy; D = double [3]; Extra = {}; type_ = Galaxy; options = {}]::<lambda(pybind11::class_<Galaxy>::type&, const double (&)[3])>; Extra = {pybind11::is_method}; <template-parameter-1-3> = void]’, declared using local type ‘pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = Galaxy; D = double [3]; Extra = {}; type_ = Galaxy; options = {}]::<lambda(pybind11::class_<Galaxy>::type&, const double (&)[3])>’, is used but never defined [-fpermissive]
cpp_function(Func &&f, const Extra&... extra) {
^~~~~~~~~~~~
Thank you in advance.
In C++, you can't assign directly to an array, which is what pybind11 is trying to do inside its wrapping magic. In general, C++ arrays are not great abstractions for numerical arrays. As you've noticed, you can't even say galaxy.x = other_galaxy.x.
Your best bet is to use a higher-level library for matrices and vectors, which will
a) give you a much better experience writing your C++
b) perform better
c) map more cleanly to Python
Eigen is a good choice. pybind11 automatically knows how to map Eigen matrices and vectors to numpy arrays. Your Galaxy would become:
class Galaxy {
public:
Eigen::Vector3d x;
Eigen::Vector3d v;
};
If you absolutely can't do this, you'll have to supply manual getter/setter functions to the property, where you do your own conversion to and from python types:
https://pybind11.readthedocs.io/en/master/classes.html?highlight=def_property#instance-and-static-fields

C++ ostream operator overloading using const argument error

I'm trying to use the standard format for non-member function overloading for the ostream operator, but it will not work with a const second argument when I have an internal assignment to a vector iterator. The compiler gives the following error when a const argument is used: error: no match for 'operator=' in j = bus.owAPI::owBus::owCompList.std::vector...
Relevant parts of my Class are as follows:
class owBus{
public:
std::vector<owComponent> owCompList; //unsorted complete list
friend std::ostream&
operator<<(std::ostream& os, const owBus& bus );
};
with the non-member function:
std::ostream& operator<<(std::ostream& os, const owBus& bus ) {
//iterate through component vector
std::vector<owComponent>::iterator j;
for(j=bus.owCompList.begin(); j!=bus.owCompList.end(); j++) {
/*
os << (*j).getComponentID() << ": ";
os << (*j).getComponentType() << std::endl;
*/
}
return os;
}
This works fine if the const is removed from the friend declaration and the second argument in the function description, otherwise it give the error described above. I don't have an assignment operator defined for the class, but it's not clear to me why that should make a difference.
That's because you're trying to use a non-const iterator to iterate through a const object. Change the declaration of j to:
std::vector<owComponent>::const_iterator j;
or just use the C++11 style:
for (auto j : bus.owCompList) {

a problem about using const char* to pass parameter

I first store the 3 value into a pair of map like this:
void AddMenuAtlasTexture( int tag, const char* filename, const char* textureName )
{
map<const char*, const char*> _item;
_item.insert(pair<const char*, const char*>(filename, textureName));
m_texturesToLoad.insert(pair<int, map<const char*, const char*> >(tag, _item));
};
then I pass the value to another function like this:
map<const char*, const char*>::iterator _content;
int _tag = (*m_texturesToLoadIterator).first;
_content = (*m_texturesToLoadIterator).second.begin();
AtlasManagerSingleton->AddAtlas((*_content).first, (*_content).second, _tag);
the "textureName" is an absolute path like this kind: "/Users/eddy/Library/Application Support/iPhone Simulator/User/Applications/5FDE0091-2E93-42FE-BB62-05A16429551D/Ranch.app/../Documents/shop_tex.png"
my problem is the first function can get the "textureName" right, but the second function "AddAtlas" can not get the path, the "(*_content).second" is NULL.
and the "AddAtlas" prototype is:
void AtlasManager :: AddAtlas( const char *a_configFile, const char *a_spriteName, int a_nKey )
I develop this in iPhone dev using XCode.
use make_pair instead of pair<int, map<const char*, const char*> >.
use -> instead of *.
the texture loader is a map int -> const char* -> const char*. I don't see where you used the second index.
Probably this:
AtlasManagerSingleton->AddAtlas((*_content).first, (*_content).second, _tag)
Should be:
AtlasManagerSingleton->AddAtlas(_content->first, _content->second.begin()->second, _tag)

does boost python support a function returning a vector, by ref or value?

I am new to python, I have looked at boost python, and it looks very
impressive. However going through the introduction I can not find
any examples where, vector of objects are returned as python list/tuples.
i.e Take this example, I want to expose class X, Cont and all its functions.
critical bit being return a vector of X's or strings to python
class X {};
class Cont {
.....
// how can this be exposed using boost python
const std::vector<X>& const_ref_x_vec() const { return x_vec_;}
std::vector<X> value_x_vec() const { return x_vec;}
const std::vector<std::string>& const_ref_str_vec() const { return str_vec_;}
std::vector<std::string> value_str_vec() const { return str_vec_; }
...
private:
std::vector<X> x_vec_;
std::vector<std::string> str_vec_;
};
My own fruitless attempt at trying to expose the functions like
const_ref_x_vec(), value_x_vec(),etc just leads to compile errors.
from googling around I have not seen any example that support returning vectors
by value or reference. Is this even possible with boost python?
are there any workarounds ? should I be using SWIG for this case ?
Any help appreciated.
Avtar
Autopulated's reason was essentially correct, but the code was more complicated then necessary.
The vector_indexing_suite can do all that work for you:
class_< std::vector<X> >("VectorOfX")
.def(vector_indexing_suite< std::vector<X> >() )
;
There is a map_indexing_suite as well.
Because you can't expose template types to python you have to explicitly expose each sort of vector that you want to use, for example this is from my code:
Generic template to wrap things:
namespace bp = boost::python;
inline void IndexError(){
PyErr_SetString(PyExc_IndexError, "Index out of range");
bp::throw_error_already_set();
}
template<class T>
struct vec_item{
typedef typename T::value_type V;
static V& get(T& x, int i){
static V nothing;
if(i < 0) i += x.size();
if(i >= 0 && i < int(x.size())) return x[i];
IndexError();
return nothing;
}
static void set(T& x, int i, V const& v){
if(i < 0) i += x.size();
if(i >= 0 && i < int(x.size())) x[i] = v;
else IndexError();
}
static void del(T& x, int i){
if(i < 0) i += x.size();
if(i >= 0 && i < int(x.size())) x.erase(x.begin() + i);
else IndexError();
}
static void add(T& x, V const& v){
x.push_back(v);
}
};
Then, for each container:
// STL Vectors:
// LineVec
bp::class_< std::vector< Line > >("LineVec")
.def("__len__", &std::vector< Line >::size)
.def("clear", &std::vector< Line >::clear)
.def("append", &vec_item< std::vector< Line > >::add,
bp::with_custodian_and_ward<1, 2>()) // let container keep value
.def("__getitem__", &vec_item< std::vector< Line > >::get,
bp::return_value_policy<bp::copy_non_const_reference>())
.def("__setitem__", &vec_item< std::vector< Line > >::set,
bp::with_custodian_and_ward<1,2>()) // to let container keep value
.def("__delitem__", &vec_item< std::vector< Line > >::del)
.def("__iter__", bp::iterator< std::vector< Line > >())
;
// ...
A similar approach is possible for std::map.
I used lots of help from wiki.python.org when writing this.