我知道不能有虚拟模板成员函数,但我想要类似它的东西。
考虑以下伪代码:
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 变体或 union ,但如果添加更多具体类,它很快就会变得笨拙。我也可以使用 Boost any,但是我必须使用 any_cast
并且它不会那么......好吧,不错和简单。
可能只是我今天的 google-fu 不好,或者我只是太累了,但我还没有找到任何解决办法。是否有可能做这样的事情,同时仍然保持足够的灵 active 以添加更多具体类,并保持界面简单美观?
关于用例的一点解释:这是我正在制作的一个简单编译器的小型词法分析器的一部分(尽管只是为了好玩),上面示例中的抽象类是“ token ”类,具体类是特定的标记,如“整数标记”或“字符串标记”或“标识符标记”。
我想使用抽象/具体类和继承的原因是因为我想让词法分析器足够灵活以供多种语言使用,所以应该很容易,例如,添加一个“标识符 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);
}
简单易行。 :)
免责声明:代码未经编译器审查。
关于c++ - 虚拟模板化成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36604392/