Getting pointer to boost::any::operator= - c++

I want to get pointer to boost::any::operator=, so i did this:
bool(__thiscall boost::any::*func)(const bool&) = &(boost::any::operator=<bool>);
but now, compiler says
initializing' : cannot convert from 'overloaded-function' to 'bool (__thiscall boost::any::* )(const bool &)'
None of the functions with this name in scope match the target type
i also tried to make it this way:
bool(__thiscall boost::any::*func)(const bool&) = static_cast<(boost::any::*)(const bool&)>(&(boost::any::operator=<bool>));
but there is compiler says: "syntax error : '('" in this line
can anybody helps me, please?
P.S. I make instaces of boost::any in the code above

You can not specify the arguments in the assignment of the member function pointer.
This will do it:
#include <iostream>
#include <boost/any.hpp>
int main() {
boost::any any = false;
std::cout << boost::any_cast<bool>(any) << std::endl;
typedef boost::any& (boost::any::*assign_operator)(const bool&);
assign_operator assign = &boost::any::operator =;
(any.*assign)(true);
std::cout << boost::any_cast<bool>(any) << std::endl;
return 0;
}

Related

C++ map of heterogeneous function

I would like to create a C++ script that uses map to execute heterogeneous functions, and stores the input/output in a map.
To deal with the heterogeneity I though to use the any type.
However, this creates problems, since the function pointer is not able to convert other type in any type.
Here is a minimal example that is not working, but illustrates what I would like to do:
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <map>
#include <any>
using namespace std;
string funct1(int a, int b)
{
int c= a+b;
string name = to_string(c);
return name ;
}
float funct2(int a, int b)
{
// float b2
float c=a-b;
return c ;
}
int main(void)
{
cout << "START" << endl;
std::map<std::string, std::any> ListObjIn; //
std::map<std::string, std::any> ListObjOut; //
typedef std::any (*FnPtr)(std::any, int);
std::map<std::string, FnPtr> ListCommand; //
//
ListObjIn["a1"] = 1;
ListObjIn["a2"] = 1.5;
ListCommand["do1"]= funct1;
ListCommand["do2"]= funct2;
// ListObjOut["res1"]= ListCommand["do1"]( std::any_cast<int>(ListObjIn["a1"]), 2);
ListObjOut["res1"]= ListCommand["do1"]( ListObjIn["a1"], 2);
cout << "RESULT 1=" << std::any_cast<string>(ListObjOut["res1"]) << endl;
ListObjOut["res2"]= ListCommand["do2"]( ListObjIn["a2"], 2);
cout << "RESULT 2=" << std::any_cast<string>(ListObjOut["res2"]) << endl;
cout << "END" << endl;
return(0);
}
I get the following error:
g++ -std=c++17 ./test.cpp
./test.cpp: In function ‘int main()’:
./test.cpp:34:24: error: invalid conversion from ‘std::__cxx11::string (*)(int, int) {aka std::__cxx11::basic_string<char> (*)(int, int)}’ to ‘std::map<std::__cxx11::basic_string<char>, std::any (*)(std::any, int)>::mapped_type {aka std::any (*)(std::any, int)}’ [-fpermissive]
ListCommand["do1"]= funct1;
^~~~~~
./test.cpp:35:24: error: invalid conversion from ‘float (*)(int, int)’ to ‘std::map<std::__cxx11::basic_string<char>, std::any (*)(std::any, int)>::mapped_type {aka std::any (*)(std::any, int)}’ [-fpermissive]
ListCommand["do2"]= funct2;
^~~~~~
I tried to change the input and output type of the function (ie string and float) to any, but this creates problems of conversion at other places.
So it is possible to have something very close to my original example, keeping the heterogeneity of type in/out and map of functions ? Or should think to workaround ? if so, which one ?
You should probably generify return type with std::any:
https://godbolt.org/z/G1EhqY

use of std::less in std::map does not compile

I am unable to understand why does following function not compile
#include <iostream>
#include <map>
int main(){
std::map<int, int, std::less<int>> myMap(std::less<int>());
myMap[2] = 2;
std::cout << myMap[2] << std::endl;
return 0;
}
The error message is as follows -
std_less_check.cpp: In function ‘int main()’:
std_less_check.cpp:6:10: warning: pointer to a function used in arithmetic [-Wpointer-arith]
myMap[2] = 2;
^
std_less_check.cpp:6:14: error: assignment of read-only location ‘*(myMap + 2)’
myMap[2] = 2;
^
std_less_check.cpp:6:14: error: cannot convert ‘int’ to ‘std::map<int, int, std::less<int> >(std::less<int> (*)())’ in assignment
std_less_check.cpp:7:23: warning: pointer to a function used in arithmetic [-Wpointer-arith]
std::cout << myMap[2] << std::endl;
while following compiles successfully
#include <iostream>
#include <map>
int main(){
std::map<int, int, std::less<int>> myMap(std::less<int>{});
myMap[2] = 2;
std::cout << myMap[2] << std::endl;
return 0;
}
Could someone please help me with this?
In the first program, you have a vexing parse. If the compiler can parse a declaration as either a variable or a function, it will choose to parse it as a function.
myMap can be parsed as a function declaration.
It returns a std::map<int, int, std::less<int>>.
It takes an argument of type std::less<int>(), which is itself a function type that returns a std::less<int> and takes no arguments. Note that you can't actually have a function type as an argument; the type is actually a pointer to a function that takes no arguments and returns a std::less<int>.
In the second program, replacing () with {} resolves the ambiguity. Now myMap can no longer be a function declaration, and so it instead declares a variable of type std::map<int, int, std::less<int>>.

C++ - Vector of function pointers inside class

I am making my own programming language. I made classes (like 'string' or 'int) that derive from the object class. I am making standard types like string and int so I have a base I can work off (expand my language with itself if that makes sense). Each standard type has a unordered_map of functions. I would love to hear a way to fix this/another approach.
When I run the program, I get this error that I don't understand:
C2664: 'std::pair<const _Kty,_Ty>::pair(std::pair<const _Kty,_Ty> &&)': cannot convert argument 2 from '_Ty' to 'const _Ty2 &'
It's referring to line 62. Where the error comes from:
c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xmemory0 line:881
The code from xmemory0:
template<class _Objty,
class... _Types>
static void construct(_Alloc&, _Objty * const _Ptr, _Types&&... _Args)
{ // construct _Objty(_Types...) at _Ptr
::new (const_cast<void *>(static_cast<const volatile void *>(_Ptr)))
_Objty(_STD forward<_Types>(_Args)...);
}
My code:
#include <iostream>
#include <unordered_map>
#include <string>
#include <functional>
struct Object;
typedef std::unordered_map<std::string, std::function<Object*(std::string*)>> stdtypefunc_map;
struct Object
{
};
struct StdType : public Object
{
stdtypefunc_map functions;
};
struct stringtype : public StdType
{
stringtype()
{
functions.emplace("GetValue", &stringtype::GetValue);
}
Object* GetValue(std::string args[])
{
std::cout << "GetValue()" << std::endl;
}
};
int main()
{
stringtype s;
return 0;
}
In your code, line 62 is this statement:
functions.emplace("GetValue", &stringtype::GetValue);
functions is an std::unordered_map whose key_type is std::string and mapped_type is std::function<Object*(std::string*)>.
emplace() constructs a new std::unordered_map::value_type in the map, passing the values you specify to the value_type's constructor. In this case, that value_type is a std::pair<const std::string, std::function<Object*(std::string*)>>, and you are passing in 2 values to constructor the std::pair with.
The error message you are seeing is basically saying that the compiler can't convert &stringtype::GetValue to std::function<Object*(std::string*)>. For example, here is a simplified example that reproduces the same failure, and GCC gives a VERY DETAILED error message explaining why it failed (which is too large to post here, so I'll post only the relevant pieces):
https://ideone.com/qVLkQd
#include <iostream>
#include <unordered_map>
#include <string>
#include <functional>
struct Object;
typedef std::unordered_map<std::string, std::function<Object*(std::string*)>> stdtypefunc_map;
struct Object
{
};
struct StdType : public Object
{
stdtypefunc_map functions;
};
struct stringtype : public StdType
{
stringtype()
{
functions.emplace("GetValue", &stringtype::GetValue);
}
Object* GetValue(std::string args[])
{
std::cout << "GetValue()" << std::endl;
}
};
int main()
{
stringtype s;
return 0;
}
/usr/include/c++/6/ext/new_allocator.h:120:4: error: no matching function for call to ‘std::pair<const std::__cxx11::basic_string<char>, std::function<Object*(std::__cxx11::basic_string<char>*)> >::pair(const char [9], Object* (stringtype::*)(std::__cxx11::basic_string<char>*))’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
/usr/include/c++/6/ext/new_allocator.h:120:4: note: cannot convert ‘std::forward<Object* (stringtype::*)(std::__cxx11::basic_string<char>*)>((* & __args#1))’ (type ‘Object* (stringtype::*)(std::__cxx11::basic_string<char>*)’) to type ‘const std::function<Object*(std::__cxx11::basic_string<char>*)>&’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
Which makes sense. You can't store a pointer-to-member-method for a non-static method into a std::function unless you take into account that it will need an object instance to call the method on. Such as by using std::bind() to bind an object instance with the pointer-to-member-method:
using std::placeholders::_1;
functions.emplace("GetValue", std::bind(&stringtype::GetValue, this, _1));
Or, by using a lambda to capture the object:
functions.emplace("GetValue", [this](std::string *args){ return this->GetValue(args); });

std::function of a value templated method compiles with clang and g++ but not with msvc

The following code compiles with clang v5.0.0 and g++ v8.1.0 but fails with visual studio (2013 and 2017):
#include <string>
#include <functional>
#include <iostream>
template <const char* name>
std::string fct() {
return name;
}
const char toto[] = "toto";
std::function<std::string()> fctptr = fct<toto>;
int main(){
std::cout << fctptr() << std::endl;
}
The error is the following:
main.cpp(11): error C2440: 'initializing' : cannot convert from 'std::string (__cdecl *)(void)' to 'std::function<std::string (void)>'
1> No constructor could take the source type, or constructor overload resolution was ambiguous
I tried to replace the std::function with a typedef to a function pointer, as such:
typedef std::string(*Fctptr)();
Fctptr fctptr = fct<toto>;
However, I got the same error.
Is it a bug with msvc compiler, or is the above code not standard compliant.
FWIW, the following failed to compile using g++ 6.4.0 (g++ -std=c++11).
#include <string>
#include <functional>
#include <iostream>
template <const char* name>
std::string fct() {
return name;
}
const char toto[] = "toto";
std::function<std::string()> fctptr = fct<toto>;
int main(){
std::cout << fctptr() << std::endl;
}
Here's the error message:
socc.cc:11:43: error: the value of ‘toto’ is not usable in a constant expression
std::function<std::string()> fctptr = fct<toto>;
^~~~
socc.cc:10:12: note: ‘toto’ was not declared ‘constexpr’
const char toto[] = "toto";
Changing the definition of toto to
constexpr char toto[] = "toto";
resolved the problem.

no known conversion for templated vs const non-templated vector

In my actual code, I included a library, and as soon as I did that, it started crashing. I managed to sort of extract some of that code into this minimal example, that demonstrates the same kind of error:
// g++ -std=c++11 -g -o test-classcall.exe test-classcall.cpp
#include <iostream>
#include <vector>
#include <stdio.h>
class Cat
{
public:
int Age;
Cat() : Age(0) {}
};
std::vector<Cat> myPCats;
typedef std::vector<Cat> TDVectCats;
TDVectCats myTDCats;
void loopSomeCats() {
printf("this function just to cause searching for matching calls\n");
}
void loopSomeCats(TDVectCats& incats) {
std::vector<Cat>::iterator iter;
for(iter = incats.begin(); iter != incats.end(); iter++) {
printf("hm\n");
}
}
const std::vector<Cat> & getSomeCats() {
return myPCats;
}
void doSomething() {
loopSomeCats(getSomeCats());
}
int main() {
myTDCats.push_back(Cat());
myTDCats.push_back(Cat());
myPCats.push_back(Cat());
doSomething();
std::cout << "Hello World! " << std::endl;
return 0;
}
The result is:
$ g++ -std=c++11 -g -o test-classcall.exe test-classcall.cpp
test-classcall.cpp: In function ‘void doSomething()’:
test-classcall.cpp:36:29: error: no matching function for call to ‘loopSomeCats(const std::vector<Cat>&)’
loopSomeCats(getSomeCats());
^
test-classcall.cpp:36:29: note: candidates are:
test-classcall.cpp:20:6: note: void loopSomeCats()
void loopSomeCats() {
^
test-classcall.cpp:20:6: note: candidate expects 0 arguments, 1 provided
test-classcall.cpp:24:6: note: void loopSomeCats(TDVectCats&)
void loopSomeCats(TDVectCats& incats) {
^
test-classcall.cpp:24:6: note: no known conversion for argument 1 from ‘const std::vector<Cat>’ to ‘TDVectCats& {aka std::vector<Cat>&}’
What especially confuses me, is the last "no known conversion for argument 1 from ‘const std::vector<Cat>’ to ‘TDVectCats& {aka std::vector<Cat>&}’", as if it cannot convert a vector of something, into the vector of the same something, just because of typedef? Or it maybe has to do with the const - but I simply cannot see what I need to change, in order to have a call like loopSomeCats(getSomeCats()); succeed...
You can't pass a reference to a const object to a non-const reference.
loopSomeCats takes a std::vector<Cat>& as argument, and you want to pass a const std::vector<Cat>& to it, but that's not possible.
The const would mean that you don't want anyone to modify the return value, but if you pass it to a function which just takes a non-const reference, then theoretically the function can modify the reference, and you don't want that.
You should drop the const if you want the return value to be modified.