recursive_wrapper and ambiguous convert_construct() [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
Do you have any idea how to solve or get around this problem?
http://boost.2283326.n4.nabble.com/Variant-recursive-wrapper-and-ambiguous-convert-construct-td4543139.html
#include <boost/variant.hpp>
class b_fwd;
typedef boost::variant<boost::recursive_wrapper<b_fwd> > a;
class c_fwd;
typedef boost::variant<boost::recursive_wrapper<c_fwd> > b;
struct b_fwd : b {
// inherit constructors
template <typename... Ts> b_fwd(Ts... o) : b(o...) {}
};
typedef boost::variant<double, char *> c;
struct c_fwd : c {
// inherit constructors
template <typename... Ts> c_fwd(Ts... o) : c(o...) {}
};
void f(const b &b_node)
{
a a_node(b_node);
}
int main()
{
}

I had a hunch in reaction to GuyGreer's comment.
If the problem is caused by variant being assignable/convertible to variant, then maybe we can disambiguate by using a third, isolated, variant:
a a_node(boost::variant<b>(b_node));
Lo and behold, homeopathy seems to work :)
See it Live On Coliru
I have no idea whether this "works" in the sense that the OP expects, because, frankly, the OP's code was a mystery to me
#include <boost/variant.hpp>
class b_fwd;
typedef boost::variant<boost::recursive_wrapper<b_fwd> > a;
class c_fwd;
typedef boost::variant<boost::recursive_wrapper<c_fwd> > b;
struct b_fwd : b {
using b::b;
};
typedef boost::variant<double, char *> c;
struct c_fwd : c {
using c::c;
};
void f(const b &b_node)
{
a a_node(boost::variant<b>(b_node));
}
int main()
{
}

Related

How to "pass" an namespace as argument? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
If I have the following code :
void foo1()
{
NS1::Type1 instance1;
NS1::Type2 instance2;
NS1::Type3 instance3;
}
void foo2()
{
NS2::Type1 instance1;
NS2::Type2 instance2;
NS2::Type3 instance3;
}
How to factorize this function ?
I can call foo1 from NS1, and foo2 from NS2.
How to “pass” an namespace as argument?
There is no way to do that.
It is possible to write a reusable template for your foos if you use classes instead of namespaces:
struct NS1 {
using Type1 = int;
using Type2 = float;
using Type3 = std::string;
};
struct NS2 {
using Type1 = long;
using Type2 = double;
using Type3 = std::string;
};
template<class T>
void foo() {
typename T::Type1 instance1;
typename T::Type2 instance2;
typename T::Type3 instance3;
}

Factory design pattern optimization [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have a class named Creation in both Creation.cc and Creation.h, and there are bunch of createA, createB, createC...etc. functions inside this class, all of them will return a pointer type.
I have a lot of modelA.cc, modelB.cc, modelC.cc ...etc. files, and all of them have included Creation.h.
Since whenever I make a new model x (make a new modelx.cc), I need to add the corresponding createx in Creation.h, which will make all model.cc files being compiled again.
All the createA, createB, createC functions have same parameter list but different input values and implementation, which are based on their model.cc.
My goal is that I don't want to recompile all model.cc when adding a new createx function.
Thanks.
A common strategy is to have the factory contain a registration method. Once a class is registered then a call is made to the factory to get an actual instance.
The C++17 example below allows sub-classes of the 'interface' to have different parameters in the call for creation. 'createInstance' is tasked with constructing an instance for a particular class.
The Any class was taken from here. As noted in the link, the createInstance call is quite particular about the input arguments matching the method signature.
#include <iostream>
#include <functional>
#include <map>
#include <string>
#include <any>
#include <functional>
#include <map>
#include <string>
#include <iostream>
struct interface
{
};
template<typename Ret>
struct AnyCallable
{
AnyCallable() {}
template<typename F>
AnyCallable(F&& fun) : AnyCallable(std::function(fun)) {}
template<typename ... Args>
AnyCallable(std::function<Ret(Args...)> fun) : m_any(fun) {}
template<typename ... Args>
Ret operator()(Args&& ... args)
{
return std::invoke(std::any_cast<std::function<Ret(Args...)>>(m_any), std::forward<Args>(args)...);
}
std::any m_any;
};
struct factory
{
std::map<std::string, AnyCallable<interface>> registry;
void registerClass(std::string const & class_name, AnyCallable<interface> function)
{
registry[class_name] = function;
}
template<typename ... Args>
interface createInstance(std::string const & class_name, Args && ... args)
{
if(registry.find(class_name) == registry.end())
{
throw "No class found";
}
return registry[class_name](std::forward<Args>(args)...);
}
};
struct A:public interface
{
A()
{
std::cout << "Create A" << std::endl;
}
static interface createInstance(int t)
{
return A();
}
static void registerWithFactory(factory& f)
{
f.registerClass("A",&createInstance);
}
};
struct B:public interface
{
B()
{
std::cout << "Create B" << std::endl;
}
static interface createInstance(std::tuple<int, double> t)
{
return B();
}
static void registerWithFactory(factory& f)
{
f.registerClass("B",&createInstance);
}
};
int main(int argc, char* argv[])
{
factory f;
A::registerWithFactory(f);
B::registerWithFactory(f);
try {
interface a = f.createInstance("A",1);
interface b = f.createInstance("B",std::tuple{1,1.0});
interface c = f.createInstance("C");
}
catch(...)
{
std::cout << "createInstance failed" << std::endl;
}
return 0;
}
All the members of the factory will descend from 'interface'. The 'factory' will allow registration of new class that are not yet created. In the example A and B exists but C does not. In the future C can be added without recompiling the existing code.
There are a variety of patterns that expand on this theme.

What is the difference between map<string, pair<string, foo*>> and map<string, pair<string, foo&>>? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I write a abstract class foo, and bar class inherits from foo.
I want create a map container that is map<string, pair<string, foo&>>, but I cannot compile successfully. The compiler tells me
“std::pair<std::string,foo &>::pair”: not appropriate default constructor
Here is code:
#include <iostream>
#include <string>
#include <windows.h>
#include <map>
#include <utility>
using namespace std;
class foo
{
public:
virtual void t() = 0;
};
class bar :public foo
{
public:
void t()
{
cout << "bar" << endl;
}
};
int main()
{
bar b;
//wrong
//map<string, pair<string, foo&>> t;
//pair<string, foo&> p("b", b);
//t["t"] = p;
//right
map<string, pair<string, foo*>> t;
pair<string, foo*> p("b", &b);
t["t"] = p;
p.second->t();
}
I want to know the difference between map<string, pair<string, foo*>> and map<string, pair<string, foo&>>.
The problem with the first example (which you labeled "wrong") is the line t["
t"] = p;. If you look at the documentation for std::map::operator[] you will find the following passage :
value_type must be EmplaceConstructible from std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>().
This implies that your mapped_type (in this case, foo&) must be default constructible. However, references must always refer to an existing object, they can't be default constructed. The example that uses pointers is fine because pointers don't have that restriction.
You can use references as the mapped_type but you will have to avoid operator[]. For example, you can find an element with std::map::find or insert one with std::map::emplace. The following example compiles fine :
#include <string>
#include <map>
#include <utility>
using namespace std;
struct foo {};
int main()
{
foo b;
//wrong
map<string, pair<string, foo&>> t;
pair<string, foo&> p("b", b);
t.emplace("t", p);
}

C++, Why can't I put the definition of class constructor with parameters-initialize list outside the class declaration [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Why can't I put the definition of class constructor with parameters-initialize list outside the class declaration?
typedef unsigned int UINT;
class num_sequence {
public:
typedef vector<UINT>::iterator iterator;
//I cannot put this following part in the cpp file
num_sequence(vector<UINT> & ele,int len=0,int beg=0):_relems(ele),_length(len),_beg_pos(beg)
{
//an abstract class cannot be instanlized
cout<<"build a num_sequence object";
}
virtual ~num_sequence();
num_sequence.h
#include <vector>
typedef unsigned int UINT;
class num_sequence
{
public:
typedef std::vector<UINT>::iterator iterator;
num_sequence(std::vector<UINT> & ele, int len = 0, int beg = 0);
virtual ~num_sequence();
private:
std::vector<UINT> &_relems;
int _length;
int _beg_pos;
};
num_sequence.cpp
#include "num_sequence.h"
#include <iostream>
num_sequence::num_sequence(std::vector<UINT> & ele, int len, int beg)
: _relems(ele), _length(len), _beg_pos(beg)
{
std::cout << "build a num_sequence object";
}
num_sequence::~num_sequence()
{
}

Keep getting unordered_map compiler error [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Header:
#include <unordered_map>
#include "O.h"
#include "P.h"
using namespace std;
class O{
public:
O();
unordered_map<int,P>* X();
unordered_map<int,P>* Y();
private:
unordered_map<int,P>* b;
unordered_map<int,P>* a;
};
source:
#include "O.h"
#include "P.h"
#include <unordered_map>
using namespace std;
O::O(){
a= new unordered_map<int,P>();
b= new unordered_map<int,P>();
}
unordered_map<int,P>* O::X(){
return b;
}
unordered_map<int,P>* O::Y(){
return a;
}
Error is:
1>O.cpp(76): error : return value type does not match the function
type 1> return b;
1>O.cpp(80): error : return value type does not match the function
type 1> return a;
I'm going crazy trying to debug this....
EDIT: Intel Compiler v13
The code you have posted is valid C++, so the issue must lie elsewhere in your code. I would check the included headers. Here is an example with a valid declaration of P:
#include <unordered_map>
using namespace std;
class P{
public:
int a = 3;
};
class O{
public:
O();
unordered_map<int,P>* X();
unordered_map<int,P>* Y();
private:
unordered_map<int,P>* b;
unordered_map<int,P>* a;
};
O::O(){
a= new unordered_map<int,P>();
b= new unordered_map<int,P>();
}
unordered_map<int,P>* O::X(){
return b;
}
unordered_map<int,P>* O::Y(){
return a;
}
int main(){
O o;
auto map = o.X();
return 0;
}
ideone: http://ideone.com/Y4ydzj