Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用CRTP将基类的子类传递给构造函数?_C++_Crtp - Fatal编程技术网

C++ 使用CRTP将基类的子类传递给构造函数?

C++ 使用CRTP将基类的子类传递给构造函数?,c++,crtp,C++,Crtp,我有以下基类: class BaseVisitor { public: virtual ~BaseVisitor() {}; }; template <class T> class Visitor { public: virtual void visit(T&) = 0; }; template <class Visitable> class Expression { public: template <typename T&g

我有以下基类:

class BaseVisitor
{
public:
    virtual ~BaseVisitor() {};
};

template <class T>
class Visitor
{
public:
    virtual void visit(T&) = 0;
};

template <class Visitable>
class Expression
{
public:

    template <typename T>
    void accept(T& visitor)
    {
        visitor.visit(static_cast<Visitable&>(*this));
    }
    void print() {
        static_cast<Visitable*>(this)->print();
    }
    void eval() {
        static_cast<Visitable*>(this)->eval();
    }

};
classbasevisitor
{
公众:
虚拟~BaseVisitor(){};
};
模板
班级访客
{
公众:
虚拟无效访问(T&)=0;
};
模板
类表达式
{
公众:
模板
无效接受(T和访客)
{
访问者访问(静态_cast(*this));
}
作废打印(){
静态_cast(此)->print();
}
void eval(){
静态_cast(this)->eval();
}
};
以及从表达式继承的类:

class Literal : public Expression<Literal>
{

protected:
    int value = 0;
public:

    Literal() {};
    Literal(int x);
    std::string print();

    int eval();
};

class Add : public Expression<Add>
{
protected:
    Literal lhs;
    Literal rhs;

public:

    Add(Literal left, Literal  right);
    void print();
    int eval();
};
class-Literal:公共表达式
{
受保护的:
int值=0;
公众:
文字(){};
文字(int x);
std::string print();
int eval();
};
类添加:公共表达式
{
受保护的:
字面lhs;
字面rhs;
公众:
添加(文字左侧、文字右侧);
作废打印();
int eval();
};
我希望能够将一个表达式传递给Add构造函数,这样我就能够调用
Add(Add(Literal(10)、Literal(20))、Literal(30)).eval()
,结果是50。
这在C++11中可能吗?

如果您使
添加一个模板,而不是硬编码,其左参数和右参数必须是文本,则它可以工作:

template<typename L, typename R>
class Add : public Expression<Add<L,R>>
{
protected:
    L lhs;
    R rhs;

public:

    Add(L left, R  right) : lhs(left), rhs(right) {}
    int eval() { return lhs.eval() + rhs.eval(); }
};
模板
类添加:公共表达式
{
受保护的:
lLHS;
R-rhs;
公众:
加(左左,右):左(左),右(右){
int eval(){return lhs.eval()+rhs.eval();}
};

编译
Add(Add(Literal(10)、Literal(20))、Literal(30)).eval()则需要C++17。如果你想让它与C++ 11一起工作,你需要编写一个类似于C++ > STD::MaMaGuang-< /Cord>的包装函数,以避免不得不编写<代码> Addio>代码>等等。您正在寻找的搜索词是(本文在底部列出了一些您可以学习的示例)。