2017-02-06 21 views
0

Возможно, я вышел из левого поля с этим вопросом, но можно ли определить функцию-член через конструктор?Инициализировать функции-члены с помощью конструктора

В моем случае я пытаюсь написать класс для выполнения надежного подгонки модели (с использованием RANSAC). Я хочу, чтобы это было обобщаемо для разных типов моделей. Например, я мог бы использовать это, чтобы определить оценку плоскости для множества трехмерных точек. Или, возможно, я мог бы определить трансформацию между двумя наборами точек. В этих двух примерах могут потребоваться различные функции ошибок и различные функции подгонки. Вместо того чтобы использовать класс, вызов статической функции может выглядеть

model = estimate(data, &fittingFunc, &errorFunc); 

Я интересно, если я могу иметь экземпляр члена для этих модульных функций?

Что-то вроде

class Estimator 
{ 
    private: 
     // estimation params 

     double errorFunc(std::vector<dtype>, double threshold); // Leave this unimplemented 
     double fittingFunc(std::vector<dtype>, Parameters p); // Leave this unimplemented 

    public: 
     Estimator(void (*fittingFunc(std::vector<dtype>, Parameters), void (*errorFunc(std::vector<dtype>, double)); 

     dtype estimate(data); // Estimates model of type dtype. Gets implemented 

}; 

Estimator::Estimator(void (*fittingFunc(std::vector<dtype>, Parameters), void (*errorFunc(std::vector<dtype>, double)) 
{ 
    fittingFunc = fittingFunc; 
    errorFunc = errorFunc; 
} 

Я полагаю, я извращается правильный синтаксис в моем примере, но я надеюсь, что вопрос ясен. В основном я спрашиваю: Может ли конструктор принимать указатели на функции в качестве аргументов и назначать им реализацию функций-членов?

Во-вторых, даже если это возможно, считается ли оно плохим?

UPDATE: Если это помогает, here is MATLAB code for robust estimation, что имеет такого рода обобщение структуры Я надеюсь повторить в C++

+0

ответ на ваш вопрос ** да **. и исправьте свой код в 'double ';' и эта точка с запятой для чего? –

+0

@ k-five: Типо, извините. И да, это возможно? Или да, это плохая форма? Или оба? – marcman

+0

[*** Pimpl idiom ***] (http://stackoverflow.com/questions/60570/why-should-the-pimpl-idiom-be-used) может быть лучшим подходом. –

ответ

4

Может конструктор принимает указатели на функцию в качестве аргументов и назначить их являются выполнение функций членов ?

No. Не является членом Функции. Но вы можете, конечно, есть открытый член указатели на функции:

class Estimator 
{ 
public: 
    double (*errorFunc)(std::vector<dtype>, double threshold); 
    double (*fittingFunc)(std::vector<dtype>, Parameters p); 

public: 
    Estimator(void (*fittingFunc(std::vector<dtype>, Parameters), void (*errorFunc(std::vector<dtype>, double)) 
    : errorFunc(errorFunc) 
    , fittingFunc(fittingFunc) 
    { } 

    dtype estimate(data);  
}; 

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


Вообще, если вы хорошо с накладными расходами, вы можете иметь члены типа std::function<double(std::vector<dtype>, double)> и std::function<double(std::vector<dtype>, Parameters)>, а затем вы можете использовать более широкий спектр вызываемых объектов (указатели на функции, но и лямбды, связанные функции-члены, и т. д.)

+0

Это, кажется, то, что я имел в виду, особенно с частными указателями. Я попробую, и если это сработает, примите это – marcman

+0

Спасибо. Я сходил с ума, пытаясь найти, где в стандарте это разрешено (что-то вроде этого) (http://ideone.com/r4rr2j), и почему я не мог заставить его работать благодаря решительным Yeses в комментариях. – user4581301

+0

@ M.M Я предложил это. – Barry

1

Да, вы можете предоставить алгоритм для вашей функции фитинга и ошибки. Вы можете сделать это, используя указатель на функцию. И есть лучшее решение, в стандартном заголовке вы найдете шаблон std :: function, который может быть сконструирован с указателем на функцию, а также с функторами или лямбда-выражениями.

Ваш класс будет что-то вроде этого:

#include <functional> 
class Estimator 
{ 
private: 
    // estimation params 
    using error_func_type = std::function<double(std::vector<dtype>,double)>; 
    using fitting_func_type = std::function<double(std::vector<dtype>,Parameters p)>; 
    fitting_func_type fittingFunc; 
    error_func_type errorFunc; 


public: 
    Estimator(fitting_funct_type fit, error_funct_type err) 
     :fittingFunc(fit),errorFunc(err){} 

    dtype estimate(data); // Estimates model of type dtype. Gets implemented 

};