У меня есть несколько функциональных объектов, которые не имеют переменных-членов. Функциональные объекты очень просты по своей природе. Все они наследуются от 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());
}