has anyone an idea how I can realize this with working code?
My wish is to fill a vector with executable methods of a class...
#include <iostream>
#include <vector>
#include <any>
class foo {
public:
void boo() {
std::cout << "WM 2018" << std::endl;
}
};
int main(int argc, char const *argv[])
{
std::vector<std::any> vec;
vec.push_back( (new foo)->boo() );
vec[0]();
return 0;
}
It seems you want std::vector<std::function<void()>>:
std::vector<std::function<void()>> vec{[](){ foo{}.boo();}};
Demo
Related
This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
can not define and init a class member by Parentheses [duplicate]
(1 answer)
Closed last month.
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
auto cmp = [](int a, int b) {
return a > b;
};
class Test {
private:
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);
};
int main(int argc, char const *argv[])
{
Test test;
return 0;
}
The output is below:
However, when I use the priority_queue in the main function, it can use the cmp.
Moreover, when I delete the 'cmp' in the 'pq'
auto cmp = [](int a, int b) {
return a > b;
};
class Test {
private:
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq;
};
int main(int argc, char const *argv[])
{
Test test;
return 0;
}
the complier told me:
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
auto cmp = [](int a, int b) {
return a > b;
};
int main(int argc, char const *argv[])
{
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);
pq.push(1);
std::cout << pq.top() << std::endl;
return 0;
}
I do not know why? I know lambda is a anonymous class, but why in a class it cannot use, in the main function it can use?
Welcome to the wonderful world of the Most Vexing Parse (well, not really, but close enough).
class Test {
private:
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq{cmp};
};
gcc 12 compiles this without any errors. Always use the uniform initialization syntax. It's your friend.
#include <iostream>
#include <vector>
class TestX {
public:
int i;
TestX(int inp1) : i(inp1){}
};
using Test = std::shared_ptr<TestX>;
int main()
{
Test a(4);
std::cout << a->i << std::endl;
}
I wanted to hide away that I am using a shared pointer, and make it look like I have just a regular class. The reason is that it is essential that my objects are never copied, but I still want the users to be able to create a vector with {obj1, obj2}. Is there a way to initialize a Test object as if there was a constructor, or do I have to use make_shared to initialize it?
You can use a class to wrap a std::shared_ptr, as follows
#include <iostream>
#include <vector>
#include <memory>
struct TestX {
int i;
TestX(int inp1) : i(inp1){}
TestX(TestX const &) = delete;
};
struct Test {
std::shared_ptr<TestX>test;
Test(int inp1) : test{std::make_shared<TestX>(inp1)}{}
int& get_i (){
return test -> i;
}
};
int main()
{
Test a(4);
Test b(1);
auto v = std::vector{a, b};
std::cout << a.get_i() << std::endl;
}
you can also derive from shared_ptr<TestX>
#include <iostream>
#include <vector>
#include <memory>
class TestX {
public:
int i;
TestX(int inp1) : i(inp1){}
};
struct Test : std::shared_ptr<TestX>{
Test( int x) : std::shared_ptr<TestX>{std::make_shared<TestX>(x)}{}
};
int main()
{
Test a(4);
std::cout << a->i << std::endl;
Test b(1);
auto v = std::vector{a, b};
}
class.h
// class.h
#pragma once
#include <string>
#include <iostream>
class TV {
public:
TV() {}
TV(std::string, std::string, std::string, std::string, std::string);
private:
int member;
};
main.cpp:
//main.cpp
#include "class.h"
TV::TV(std::string a, std::string b, std::string c, std::string d, std::string e) {
try {
member = std::stol(a);
if (member <= 0)
throw;
}
catch (...) {
std::cout << "Invalid argument" << std::endl;
}
}
int main(int argc, char *argv[]) {
new TV("TEST","NAME","0.1","0.1","0.1");
};
So it turns out that if I provided std::stol with an invalid_argument, then in gdb all other arguments passed to the function would appear corrupted.
Can anyone explain why this happens?
I was tinkering with a vector of std::function like this:
#include "stdafx.h"
#include <stdexcept>
#include <functional>
#include <iostream>
#include <vector>
typedef std::function<void(int)> FuncType;
std::vector<FuncType> container;
int _tmain(int argc, _TCHAR* argv[])
{
container.push_back([](int i){std::cout << i+1 << std::endl;});
container.push_back([](int i){std::cout << i+42 << std::endl;});
for(auto & o : container)
{
o(4);
}
return 0;
}
which basically just returns 5 and 46 and was thinking whether I can change the declaration of the container to some sort of wrapper class but to maintain the push back of the lambdas (= not changing anything else except declaration).
Currently I tried to implement some stub wrapper doing nothing in particular which should just compile, but it seems that the conversion from lambda to Wrapper cannot be done implicitly.
#include "stdafx.h"
#include <stdexcept>
#include <functional>
#include <iostream>
#include <vector>
typedef std::function<void(int)> FuncType;
template<class T>
class Wrapper
{
public:
Wrapper(T t)
{
_t = t;
}
void operator()(int i) const
{
_t(i);
}
protected:
T & _t;
};
std::vector<Wrapper<FuncType>> container; // Only line changed
int _tmain(int argc, _TCHAR* argv[])
{
container.push_back([](int i){std::cout << i+1 << std::endl;});
container.push_back([](int i){std::cout << i+42 << std::endl;});
for(auto & o : container)
{
o(4);
}
return 0;
}
The goal here is to wrap the call to o(int)and output some diagnostics e.g.
o.target_type().name() or performance values etc but without altering the push_back into the container to Wrapper (avoiding macro magic too)
Note: As I am using VS 2012 where variadic template arguments are not yet implemented, the standard MS std::function resorted to some macro magic like _VARIADIC_EXPAND_P1_1(_CLASS_FUNC_CLASS_1, , , , ) to provider operator()
You're trying to go through two user-defined conversions, and that's illegal in C++. Instead, make the constructor a constrained template. See below:
#include <functional>
#include <utility>
#include <iostream>
#include <vector>
#include <type_traits>
typedef std::function<void(int)> FuncType;
template<class T>
class Wrapper
{
public:
template<typename U,
typename std::enable_if<
std::is_constructible<T, U>::value,
int
>::type = 0>
Wrapper(U t)
: _t(std::move(t))
{}
void operator()(int i) const
{
_t(i);
}
private:
T _t;
};
std::vector<Wrapper<FuncType>> container; // Only line changed
int main(int argc, char* argv[])
{
container.push_back([](int i){std::cout << i+1 << std::endl;});
container.push_back([](int i){std::cout << i+42 << std::endl;});
for(auto & o : container)
{
o(4);
}
}
I am trying to create a map to hold functions that can be registered and fired. I cannot seem to get the correct bind / function / pointer syntax in order to get this compiling properly.
Here is what I have: I have tried both boost::bind and boost:
#include <cstdlib>
#include <iostream>
#include <boost/bind/bind.hpp>
#include <boost/function.hpp>
#include <map>
using namespace std;
typedef const std::string& listenArg;
typedef void (*Actions)(listenArg str);
std::multimap<int, Actions> functions;
// fire in the hole!
void fire(int methods, listenArg arg0) {
std::multimap<int, Actions>::iterator function = functions.find(methods);
typedef std::pair<int, Actions> pear;
for (function = functions.begin(); function != functions.end(); ++function) {
(*(function->second))(arg0);
}
}
void listen1(listenArg arg0) {
std::cout << "listen1 called with " << arg0 << std::endl;
}
class RegisteringClass {
public:
RegisteringClass();
virtual ~RegisteringClass();
void callMeBaby(listenArg str) {
std::cout << "baby, i was called with " << str << std::endl;
}
};
int main(int argc, char** argv) {
const int key = 111;
functions.insert(make_pair<int, Actions>(key, listen1));
fire(key, "test");
// make a registeringClass
RegisteringClass reg;
// register call me baby
boost::function<void (listenArg) >
fx(boost::bind(&RegisteringClass::callMeBaby, reg, _1));
//std::bind(&RegisteringClass::callMeBaby, reg, _1);
functions.insert(
make_pair<int, Actions> (key, fx));
// fire
fire(key, "test2");
return 0;
}
Thanks for any help!
typedef boost::function < void (listenArg) > Actions;
Should be used instead of function pointer.
The problem is that you're telling the compiler that Actions is a non-member function pointer, and then you try to put a boost::function into a variable of that type. They're two totally unrelated types and such an assignment can't happen. You need to make your Actions typedef be a boost::function<void (listenArg)> instead.
you can use boost::function template
#include <cstdlib>
#include <iostream>
#include <boost/bind/bind.hpp>
#include <boost/function.hpp>
#include <map>
using namespace std;
typedef const std::string& listenArg;
typedef boost::function < void (listenArg) > Actions;
std::multimap<int, Actions> functions;