#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};
}
Related
I'm trying to make a program with #include <future> library.
When I try to access a header function, I get an error.
no instance of overloaded function "async" matches the argument list -- argument types are: (std::launch, int ()) [line 16, 14]
a pointer to a bound function may only be used to call the function
[line 16, 37]
main.cpp:
#include "TEST.h"
#include <future>
#include <iostream>
using namespace std;
using namespace Class;
FNH f;
int main(){
auto fn = async(launch::async, f.selam);
}
TEST.h:
#pragma once
#include <iostream>
using namespace std;
namespace Class{
class FNH{
public:
int selam(){
cout << "selam";
return 1;
}
};
}
I'm a beginner at coding so I really don't know how to fix it or if it's possible.
You can pass a member function pointer and the instance of the class it will be called on:
#include <future>
#include <iostream>
namespace Class {
class FNH {
public:
int selam(){
std::cout << "selam";
return 1;
}
int selam_2(int a, int b){
std::cout << "selam "<< a << " " << b;
return 1;
}
};
}
int main(){
Class::FNH f;
// Member Function Pointer
auto fn = std::async(std::launch::async, &Class::FNH::selam, f);
// Member Function Pointer with arguments
auto fn2 = std::async(std::launch::async, &Class::FNH::selam_2, f, 1, 2);
}
Put the method call in a lambda
#include <future>
#include <iostream>
namespace Class{
class FNH {
public:
int selam(){
std::cout << "selam";
return 1;
}
};
}
int main(){
Class::FNH f;
auto fn = std::async(std::launch::async, [&f]{ return f.selam(); });
}
I am relatively new to CPP and have recently stumbled upon std::variant for C++17.
However, I am unable to use the << operator on such type of data.
Considering
#include <iostream>
#include <variant>
#include <string>
using namespace std;
int main() {
variant<int, string> a = "Hello";
cout<<a;
}
I am unable to print the output. Is there any short way of doing this? Thank you so much in advance.
You can use std::visit if you don't want to use std::get.
#include <iostream>
#include <variant>
struct make_string_functor {
std::string operator()(const std::string &x) const { return x; }
std::string operator()(int x) const { return std::to_string(x); }
};
int main() {
const std::variant<int, std::string> v = "hello";
// option 1
std::cout << std::visit(make_string_functor(), v) << "\n";
// option 2
std::visit([](const auto &x) { std::cout << x; }, v);
std::cout << "\n";
}
use std::get
#include <iostream>
#include <variant>
#include <string>
using namespace std;
int main() {
variant<int, string> a = "Hello";
cout << std::get<string>(a);
}
If you want to get automatically, it can't be done without knowing its type. Maybe you can try this.
string s = "Hello";
variant<int, string> a = s;
cout << std::get<decltype(s)>(a);
#include <iostream>
#include <variant>
#include <string>
int main( )
{
std::variant<int, std::string> variant = "Hello";
std::string string_1 = std::get<std::string>( variant ); // get value by type
std::string string_2 = std::get<1>( variant ); // get value by index
std::cout << string_1 << std::endl;
std::cout << string_2 << std::endl;
//may throw exception if index is specified wrong or type
//Throws std::bad_variant_access on errors
//there is also one way to take value std::visit
}
Here is the description link: https://en.cppreference.com/w/cpp/utility/variant
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
I am trying to print struct members as follows:
#include <iostream>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
struct Node {
int a = 4;
double b = 2.2;
};
BOOST_FUSION_ADAPT_STRUCT(Node, a, b)
int main() {
Node n;
for (auto el: n) { // What do I put instead of n here?
std::cout << el << std::endl;
}
return 0;
}
This is wrong of course, since n is just a struct. How do I put for a sequence that the range for can work with instead of n?
You cannot use range-based for for this case. It's metaprogramming, each member iterator has its own type. You can traverse using fusion::for_each, or with hand-writen struct.
#include <iostream>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/for_each.hpp>
struct Node {
int a = 4;
int b = 2.2;
};
BOOST_FUSION_ADAPT_STRUCT(Node, a, b)
struct printer
{
template<typename T>
void operator () (const T& arg) const
{
std::cout << arg << std::endl;
}
};
int main() {
Node n;
boost::fusion::for_each(n, printer());
return 0;
}
I'm new with the Boost library, and I got a problam a bit complex for me.
I tried to reformulate it with an example found in previous question that might fit well my problem.
(The previous question is here)
#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
: public boost::enable_shared_from_this<Base>,
private boost::noncopyable
{
public:
virtual void test() = 0;
protected:
virtual void foo(int i) = 0;
};
class Derived
: public Base
{
protected:
void foo(int i)
{ std::cout << "Base: " << i << std::endl; }
std::map<int, int> data;
public:
Derived()
{
data[0] = 5;
data[1] = 6;
data[2] = 7;
}
void test()
{
std::for_each(data.begin(), data.end(),
boost::bind(&Derived::foo, shared_from_this(),
boost::bind(&std::map<int, int>::value_type::second, _1)));
}
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
std::set<Base_ptr> Bases_;
Base_ptr derived(new Derived());
Bases_.insert(derived);
derived->test();
return 0;
}
I have a base object which is contained in a set, and different derived objects (in this example, only one).
The derived object should call his own protected method with a boost::bind.
In the real problem, the boost::bind generate a callback method for an asynchronous operation, it's why (I think) I need a shared_ptr.
Otherwise, using the pointer this instead of shared_from_this() resolve the problem.
When I compile this code, I got a long error message ended with (which I think is the most significant part):
bind_test.cpp:43:78: instantiated from here
/usr/include/boost/bind/mem_fn_template.hpp:156:53: error: pointer to member type ‘void (Derived::)(int)’ incompatible with object type ‘Base’
/usr/include/boost/bind/mem_fn_template.hpp:156:53: error: return-statement with a value, in function returning 'void'
I tried to manage with more inheritance from enable_shared_from_this, and some static cast :
#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
: public boost::enable_shared_from_this<Base>,
private boost::noncopyable
{
public:
virtual void test() = 0;
protected:
virtual void foo(int i) = 0;
};
class Derived
: public boost::enable_shared_from_this<Derived>,
public Base
{
protected:
void foo(int i)
{ std::cout << "Base: " << i << std::endl; }
std::map<int, int> data;
public:
Derived()
{
data[0] = 5;
data[1] = 6;
data[2] = 7;
}
void test()
{
std::for_each(data.begin(), data.end(),
boost::bind(&Derived::foo, boost::enable_shared_from_this<Derived>::shared_from_this(),
boost::bind(&std::map<int, int>::value_type::second, _1)));
}
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
std::set<Base_ptr> Bases_;
Base_ptr derived(new Derived());
Bases_.insert(derived);
derived->test();
return 0;
}
But I got an error at run-time :
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
what(): tr1::bad_weak_ptr
Might someone have a clue about how to manage that ?
Thanks.
Etienne.
It works with this workaround, but I'm not satisfied with it, so if someone find a better solution, go ahead.
#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
: public boost::enable_shared_from_this<Base>,
private boost::noncopyable
{
public:
virtual void test() = 0;
//protected:
virtual void foo(int i) = 0;
};
class Derived
: public Base
{
protected:
void foo(int i)
{ std::cout << "Base: " << i << std::endl; }
std::map<int, int> data;
public:
Derived()
{
data[0] = 5;
data[1] = 6;
data[2] = 7;
}
void test()
{
std::for_each(data.begin(), data.end(),
boost::bind(&Base::foo, shared_from_this(),
boost::bind(&std::map<int, int>::value_type::second, _1)));
}
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
std::set<Base_ptr> Bases_;
Base_ptr derived(new Derived());
Bases_.insert(derived);
derived->test();
return 0;
}