繁体   English   中英

虚拟模板成员函数

[英]Virtual templated member function

我知道不能有一个虚拟的模板化成员函数,但是我想要类似的东西。

考虑以下伪代码:

struct abstract
{
    template<typename T>
    virtual T get() const = 0;
};

using abstract_pointer = std::shared_ptr<abstract>;

struct concrete_int : public abstract
{
    template<>
    int get() const { return 123; }
};

struct concrete_string : public abstract
{
    template<>
    std::string get() const { return "abc"; }
};

abstract_pointer factory()
{
    // Some logic here to decide what concrete type to return
    return ...;
}

void print_value(abstract_pointer p)
{
    // Will print either 123 or "abc"
    std::cout << "p = " << p->get() << '\n';
}

int main()
{
    abstract_pointer p = factory();

    print_value(p);
}

主代码将只使用abstract_pointer类型,它实际上应该对具体类一无所知。

可以使用CRTP和类型推导轻松解决它,但是实际上不可能像上面的示例那样将对象传递给其他函数。

我也可以使用Boost变量或联合,但是如果添加更多具体的类,它很快就会变得笨拙。 我也可以使用Boost any,但是那时我将不得不使用any_cast ,事实并非如此……很好, 很好而且很简单。

可能只是我的google-fu今天不好,或者我太累了,但是我还没有真正找到解决方法。 是否可以做这样的事情,同时又保持足够的灵活性以添加更多具体的类,并保持界面简单美观?


关于用例的一些解释:这将成为我正在制作的简单编译器的小型词法分析器的一部分(尽管只是出于娱乐目的),并且上面示例中的抽象类是“ token”类,并且具体的类是特定的令牌,例如“整数令牌”或“字符串令牌”或“标识符令牌”。

我想使用抽象/具体类和继承的原因是因为我想使词法分析器足够灵活,以供多种语言使用,因此应该很容易,例如,为“关键字”添加“标识符令牌”子类令牌”,甚至可能每个关键字只有一个具体的类。

但是也许亚伦我是对的,我努力使事情变得复杂。 如果有人提出了一个好的解决方案,或者找到了一个很好的副本,我将解决这个问题,与此同时,我会考虑更多的问题,看看我是否可以提出自己可接受的方案。

struct abstract
{
    virtual string get() const = 0;
};

using abstract_pointer = std::shared_ptr<abstract>;

struct concrete_int : public abstract
{
    string get() const override { return "123"; }
};

struct concrete_string : public abstract
{
    string get() const override { return "abc"; }
};

abstract_pointer factory()
{
    // Some logic here to decide what concrete type to return
    return ...;
}

void print_value(abstract_pointer p)
{
    // Will print either 123 or "abc"
    std::cout << "p = " << p->get() << '\n';
}

int main()
{
    abstract_pointer p = factory();

    print_value(p);
}

十分简单。 :)

免责声明:编译器未审查代码。

如果您打算引入新的关键字作为令牌,并同时使用通用智能指针来访问所有令牌,则“令牌:: get()”返回的内容必须足以被用户理解,这在某种程度上是有必要的。调用“ token :: get()”的代码。 在这里将“令牌”视为一个抽象类。

如果要通过“ get()”打印(使用“ cout”)令牌,并且如果某些具体的令牌返回对象,则“ cout”将无法理解该对象是什么或如何打印该对象。

在这种情况下,将所有标记转换为某种常见的基本类型(例如,“ Cheers and hth。-Alf”建议使用“ char *”或“ string”)似乎很好。

另外,如果打印是其中之一,则可以将以下函数添加到抽象类中:

virtual void token::print(ostream &);

这样,每个具体对象都会打印自己。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM