【问题标题】:Recurring variadic template class parameters重复可变参数模板类参数
【发布时间】:2017-03-31 22:39:31
【问题描述】:

我想要一个可变参数模板类(比如N 模板参数)来定义N 成员函数,每个函数都从参数列表中获取一个类型的参数。我试过这个:

template<class Derived, class... DerivedOthers>
class VtfVisitor : public VtfVisitor<DerivedOthers...>
{
public:
    virtual void visit(Derived& derived) = 0;
};

template<class Derived>
class VtfVisitor
{
public:
    virtual void visit(Derived& derived) = 0;
};

这不起作用,因为我无法重新定义模板类。然后我尝试了Bo提出的解决方案:

template<class Derived, class... DerivedOthers>
class VtfVisitor : public VtfVisitor<DerivedOthers...>
{
public:
    virtual void visit(Derived& derived) VISITOR_CVQ = 0;
};

template<class Derived>
class VtfVisitor<Derived>
{
public:
    virtual void visit(Derived& derived) VISITOR_CVQ = 0;
};

这仍然不起作用:使用 VtfVisitor&lt;D1,D2&gt; 尝试此操作时,成员函数 visit(D2&amp;) 未在实例化模板类中定义(而 visit(D1&amp;) 已明确定义)。

我怎样才能让它按预期工作?

感谢您的帮助。

【问题讨论】:

    标签: c++ templates variadic-templates


    【解决方案1】:

    你需要把省略号放在模板参数列表之外

    template<class Derived, class... DerivedOthers>
    class VtfVisitor : public VtfVisitor<DerivedOthers>...
    {
    public:
        virtual void visit(Derived& derived) = 0;
    };
    

    例如,如果DerivedOthers...{int, char, float},您将得到以下扩展:

    class VtfVisitor : public VtfVisitor<char>, VtfVisitor<float>
    {
    public:
        virtual void visit(int& derived) = 0;
    };
    

    【讨论】:

    • 虽然这会起作用,但这会创建一个具有多重继承的类,我想避免这种情况。但是,您的解决方案有效,谢谢。
    【解决方案2】:

    编译器认为您正在使用不同数量的参数重新声明同一个类。

    要为单参数情况创建特化,您必须在类名之后指定:

    template<class Derived>
    class VtfVisitor<Derived>
    {
    public:
        virtual void visit(Derived& derived) = 0;
    };
    

    【讨论】:

    • 哦,是的……这是一个专业。这令人困惑,因为相同的模式适用于模板函数,在这种情况下,它定义了一个新函数而不是专门化。感谢您的帮助。
    • 是的,函数可以重载,类不能。
    • 嗯,实际上,这并没有按预期工作。当我定义一个继承自VtfVisitor&lt;T1,T2&gt; 的类时,成员函数virtual void VtfVisitor&lt;T1,T2&gt;::visit(D2&amp;) 没有定义。这是什么不工作?
    • 你如何决定它是否被定义?模板化基类的成员在派生类中不可见,除非使用using 导入或使用this-&gt; 访问。尤其是在特殊化的情况下,编译器不能假设所有基类都具有相同的成员。
    • 我不知道,谢谢。不过这很令人困惑,因为VtfVisitor&lt;T1,T2&gt;::visit(D1&amp;) 在派生类中有很好的定义,而VtfVisitor&lt;T1,T2&gt;::visit(D2&amp;) 不是...
    猜你喜欢
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 2012-07-10
    • 2016-12-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多