2016-09-05 2 views
-1

Возможно ли создать функтор с несколькими конструкторами? Я хочу иметь возможность использовать функтор различными способами, инициализируя его различные члены по-разному, все в зависимости от того, какой конструктор используется для его первоначальной настройки.Функтор C++ (C++ 98) с несколькими конструкторами?

Но есть ли более элегантное решение, чем тот, который я предлагаю здесь, используя функторы с несколькими конструкторами?

Этот добавленный уровень повторного использования будет очень хорошо работать в интерпретаторе протокола проводной связи, который я пишу. Конкретный провод (или подмножество проводов) в линии связи часто может использоваться в разных целях в зависимости от конкретного используемого протокола. Поэтому я хотел бы создать небольшой набор функторов, которые могут быть адаптированы в разумных параметрах, вместо того, чтобы создавать большой набор очень специфических функторов, каждый из которых имеет сравнительно малое приспособляемость.

Затем будет использоваться меньший набор высокоадаптируемых функторов по одному в качестве параметра для функции шаблона в другом классе, эта функция может либо читать, либо записывать данные в соответствии с «правилами», воплощенными в functor используется для вызова этой функции шаблона.

Моя цель - сделать код максимально универсальным, чтобы можно было использовать множество различных подстановок протоколов и под-протоколов с одним и тем же базовым кодом.

+3

Ответ «да», но я чувствую, что это не отвечает на ваш реальный вопрос. Каков ваш реальный вопрос? – nwp

+0

Функтор - это по существу структура с оператором()() –

+2

Нет такой вещи, как C++ 99. Возможно, вы имеете в виду 98? –

ответ

0

Я не уверен, что я понимаю ваш вопрос. Прямой ответ: да, вы можете даже перегрузить оператор().

class MyFunctor { 
public: 
    MyFunctor(int a) : a(a), b(0.0) {} 
    MyFunctor(double b) : a(0), b(b) {} 

    int operator()(int c) const { return a + c; } 
    double operator()(double c) const { return b + c; } 
private: 
    int a; 
    double b; 
}; 

MyFunctor fromInt(2); 
MyFunctor fromDouble(2.1); 

std::cout << fromInt(3) << std::endl; // Print 5 
std::cout << fromInt(3.1) << std::endl; // Print 3.1 

std::cout << fromDouble(2) << std::endl; // Print 2 
std::cout << fromDouble(2.2) << std::endl; // Print 4.3 

Однако, я считаю, что это нарушает Single responsibility principle. Лучшим решением может быть создание нескольких небольших функторов и выбор лучшего из них с использованием фабрики.

class MyFunctorInt { 
public: 
    MyFunctorInt(int a) : a(a) {} 
    int operator()(int c) const { return a + c; } 
private: 
    int a; 
}; 
class MyFunctorDouble { 
public: 
    MyFunctorDouble(double b) : b(b) {} 
    double operator()(double c) const { return b + c; } 
private: 
    double b; 
}; 

MyFunctorInt createFunctor(int a) 
{ return MyFunctorInt(a); } 
MyFunctorDouble createFunctor(double b) 
{ return MyFunctorDouble(b); } 

template<class Callable, class Real> 
void myGenericFunction(const Callable &f, Real a) 
{ std::cout << f(a) << std::endl; } 

myGenericFunction(createFunctor(2),3); // Print 5 
myGenericFunction(createFunctor(2.2),3); // Print 5.2 

Это, вероятно, лучше, потому что если вы хотите добавить новую возможность для своего кода, например, для строк вы можете просто создать новый файл, в котором есть новый класс MyFunctorString и новая перегрузка в createFunctor (std :: string). Вы можете легко тестировать этот новый класс, и вам не нужно беспокоиться о взаимодействии между различными перегрузками. Например, в первый раз, когда я написал код для MyFunctor, я забыл инициализировать все члены до 0, что приведет к неопределенным результатам.

+0

kevin-> Ваш заводский подход с использованием нескольких небольших функторов - очень интригующее решение! Это хорошо, потому что, хотя мне нужно будет создать набор функторов для удовлетворения моих потребностей, детали и механика выбора того, какой функтор (ы) использовать в каждой ситуации, довольно красиво инкапсулированы и скрыты. Это очень удобно, как вы говорите, и это мощно. Действительно очень приятно! Позвольте мне поэкспериментировать с этим, и я вернусь к вам с результатами и вопросами. – user2680840

Смежные вопросы