我有一个类存储固定大小的数据
template<size_t SIZE> class Data {...};
现在我有不同的算法来生成数据(例如伪随机生成器):
class PseudoRandom1 {
template<size_t SIZE> Data<SIZE> generate();
};
class PseudoRandom2 {
template<size_t SIZE> Data<SIZE> generate();
};
现在我想要动态运行时决定调用这些生成器中的哪一个。使用虚拟模板(我知道这是不可能的),它将是以下内容:
class Generator {
virtual template<size_t SIZE> Data<SIZE> generate() = 0;
};
class PseudoRandomX : public Generator {
template<size_t SIZE> Data<SIZE> generate() override {...}
};
不幸的是,我无法将数据类的 SIZE 参数更改为非模板运行时参数。此外,我需要实际的生成器实例作为运行时决策,因为用户可以选择生成器算法。 如果可能的话,我更喜欢类型安全的解决方案(即没有 boost::any)。
我知道虚拟模板是不可能的。还有其他方法可以解决这个问题吗?
最佳答案
类型删除是你的 friend 。在您的情况下,您可以使用提供一半样板的 std::function
。另一半是编写一个包装器,将您的 generate
转换为 operator()
。
template<std::size_t N, class T>
struct generator_adapter
{
auto operator()() { return generator_.template generate<N>(); }
T generator_;
};
template<size_t Size>
using AnyRandomGenerator = std::function< Data<Size>() >;
template<size_t Size, class T>
auto as_any_generator(T g)
{
return AnyRandomGenerator<Size>( generator_adapter<Size,T>{g} );
}
AnyRandomGenerator<4> f = as_any_generator<4>(PseudoRandom1());
您的generate
函数需要公开,或者您可以让您的生成器成为generator_adapter
的 friend 。
如有必要,修改此示例以使用完美转发。
关于c++ - 替代虚拟模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33510990/