【发布时间】:2012-01-24 05:31:38
【问题描述】:
我有一些没有成员变量的函数对象。函数对象本质上非常简单。它们都继承自unary_function<> 或binary_function<>。例如,几个函数对象可能是这样的:
struct key_to_hash_method_1 : public binary_function<int, int, int>
{
int operator() (int a, int b) const { /* do something */ }
};
template <typename key_to_hash_method>
struct hash_shrink_method_1 : public binary_function<int, int, int>, public key_to_hash_method
{
int operator() (int a, int b) const { /* do something while utilizing key_to_hash_method */ }
};
/* and more variations of these function objects */
模板类通过将它们作为模板参数作为策略来使用这些函数对象。然后模板类从它们继承:
template <typename hash_method>
class foo : public hash_method
{
public:
/* do something while using hash_method as well as using the information provided by binary_function<> to selective compile different functions*/
};
当然,为了使示例简单,就实用性而言,上述内容可能没有多大意义。
为什么我要继承而不是使用组合?只是为了避免空类占用空间。节省的空间是否微不足道不是问题的重点。
从上面的代码可以看出,binary_function<int, int, int> 会被继承两次,从而产生警告(在 VC++ 2008 中):
Warning 1 warning C4584: 'hash_shrink_method_1<key_to_hash_method>' : base-class 'std::binary_function<_Arg1,_Arg2,_Result>' is already a base-class of 'key_to_hash_method_1' c:\visual studio 2008\projects\defaulttemplatearguments\main.cpp 12
现在一般来说,在多重继承中,这是通过虚拟继承来解决的;在这种情况下我想避免这种情况。在这种情况下我能做些什么来消除警告?
我的直接解决方案是不从binary_function<> 继承,因为我假设key_to_hash_method 将是binary_function。这个解决方案感觉有点像一个程序员,他无法访问包含警卫或pragma once 语句。是的,他可以避免两次包含标题,但他宁愿编译器为他解决这个问题。在这种情况下,我也希望如此。
示例代码,如果您想尝试一下:
#include <functional>
using namespace std;
struct key_to_hash_method_1 : public binary_function<int, int, int>
{
int operator() (int a, int b) const { return a + b; }
};
template <typename key_to_hash_method>
struct hash_shrink_method_1 : public binary_function<int, int, int>, public key_to_hash_method
{
int operator() (int a, int b) const { return key_to_hash_method::operator()(1, 2) * 5; }
};
template <typename hash_method>
class foo : public hash_method
{
public:
int test()
{
/* in actual code, this function selectively calls other functions
depending on whether hash_method is unary or binary */
return hash_method::operator()(5, 6);
}
};
int main()
{
foo<hash_shrink_method_1<key_to_hash_method_1> > f;
printf("%i\n", f.test());
}
【问题讨论】:
标签: c++ templates multiple-inheritance