如何绕过模板虚函数来达到我的目标?
我知道这不是合法的 C++,因为编译器无法确定 vtable 到底有多大。我正在寻找替代方案。
基本上,我有一个抽象基类,定义一组派生类的接口。通过此接口公开的某些函数的返回值由输入参数 sKeyName 确定。我想要的代码发布在下面。
class DataAccess
{
public:
template <class T>
virtual const Array2D<T>* GetData(std::string sKeyName) const = 0;
template <class T>
virtual Array2D<T>* GetData(std::string sKeyName) = 0;
};
有人可以给我一个解决方法来获得此功能吗?任何帮助表示赞赏。先感谢您。
I know this isn't legal C++ due to the compiler not being able to determine how big exactly the vtable is. I'm looking for alternatives.
Basically, I have an abstract base class defining the interface for a set of derived classes. The return values of some of the functions being exposed through this interface are determined by the input parameter sKeyName. My intended code is posted below.
class DataAccess
{
public:
template <class T>
virtual const Array2D<T>* GetData(std::string sKeyName) const = 0;
template <class T>
virtual Array2D<T>* GetData(std::string sKeyName) = 0;
};
Can somebody give me a workaround to get this functionality? Any help is appreciated. Thank you in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您需要做的是定义一个单独的模板化界面。
这可能可以满足您的需求。您还可以模板化基类,但我猜这是不允许的。
What you'd need to do is define a separate, templated interface.
This might get you what you need. You can also template the base class, but I'm guessing that's not allowed.
您问的是动态函数,但您的主要问题不在那里,而是在这里:
C++ 是一种静态类型语言,这意味着函数的返回类型不能依赖于参数的值。暂时忽略继承,您提供的代码要求用户确定返回的数组的类型独立于传递的参数:
现在,如果您愿意接受这一点(即调用者将知道并设置返回类型)有不同的方法可以为您的语言不允许模板化虚拟函数的特定问题提供解决方法。我首先想到的很好,因为它也遵循 NVI 惯用法(并显示了其重要性):提供数据的非虚拟公共模板访问器,并根据固定返回类型的虚拟函数来实现它。
假设我们可以解析
Type
和convert
是什么,我们就有了一个解决方案。这是 NVI 习惯用法的一个很好的例子:用户提供的接口(公共、非虚拟)与扩展所需的接口(私有、虚拟)不同。这两个合约不同,您的用户要求您提供指向特定具体array2d
实例化的指针,但该语言不允许您从扩展中要求相同的合约,但这不是问题,因为它们是不同的接口。现在回到
类型
和转换
。这两者是相关的,您可以遵循不同的方法。最简单的实现是拥有一个array2d_base
类,所有array2d
都从中派生(通过提供虚拟析构函数来启用 RTTI):如果您无法扩展或修改
array2d
类,那么可以通过类型擦除的方式达到类似的结果。这样做的优点是在 array2d 中不需要 RTTI,而只需要类型擦除支持。最简单的实现是在内部接口中使用boost::any
:You are asking about dynamic functions, but your main problem is not there, but rather here:
C++ is a statically typed language, and that means that you cannot have a return type for a function that is dependent on the value of the arguments. Ignoring for the time being inheritance, the code that you presented requires the user to determine the type of the array that is being returned independently of the arguments passed:
Now, if you are willing to live with that (i.e. the caller will know and set the return type) there are different ways of providing workarounds for your particular problem of the language not allowing templated virtual functions. The first thing that comes to mind is nice in that it also follows the NVI idiom (and shows its importance): Provide a non-virtual public templated accessor to the data, and implement it in terms of a fixed return type virtual function.
Assuming that we can resolve what
Type
andconvert
are, we have a solution. This is a good example of the NVI idiom: the interface offered by users (public, non virtual) differs from the interface required to extensions (private, virtual). The two contracts differ, your users require you to provide a pointer to specific concretearray2d
instantiation, but the language does not allow you to require that same contract from your extensions, but that is not a problem because they are different interfaces.Now back to
Type
andconvert
. These two are related, and there are different approaches that you can follow. The simplest to implement would be having anarray2d_base
class from which allarray2d<T>
derive (by providing a virtual destructor you enable RTTI):If you cannot extend or modify the
array2d
class, then you can achieve a similar result by means of type erasure. This will have the advantage of not requiring RTTI inarray2d
but only in the type erasing support. The simplest such implementation would be usingboost::any
in the inner interface:我不确定这是否回答了您的问题,但您可以查看 CRTP。然后你会这样做:
I am not sure if this answers your question, but you can take a look into CRTP. Then you would do :
Array2D
需要一个模板参数。即使模板类的类型是默认的,也需要<>
。Array2D
needs a template parameter. Even if type of template class is default,<>
is needed.让可以从 GetData 返回的所有不同类型继承基类并返回指向该类的指针。例子:
Let all your different types, that can be returned from GetData, inherit from a base class and return a pointer to that class. Example: