2016-10-12 2 views
6

J'essaie de comprendre pourquoi un foncteur avec un constructeur ne peut pas être passé à un algorithme, alors qu'un foncteur sans constructeur peut l'être.Comment puis-je construire un foncteur à utiliser avec un algorithme comme boost brent_find_minima?

Pour l'algorithme boost-brent_minima. Le code exemple fonctionne très bien, lorsque le foncteur n'a pas de constructeur:

#include <boost/math/tools/minima.hpp> 

struct funcdouble 
{ 
    double operator()(double const& x) 
    { // 
    return (x + 3) * (x - 1) * (x - 1); // (x + 3)(x - 1)^2 
    } 
}; 

int bits = std::numeric_limits<double>::digits; 

std::pair<double, double> r = brent_find_minima(funcdouble(), -4., 4./3, bits); 

std::cout.precision(std::numeric_limits<double>::digits10); 
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl; 

Cependant, quand j'utilise un constructeur pour générer un foncteur personnalisé comme celui-ci:

struct solver_test{ 

    solver_test::solver_test(std::string expression_string, std::string x_name_) : x_name(x_name_){ 
     symbol_table.add_constants();  
     symbol_table.create_variable(x_name); 
     expression.register_symbol_table(symbol_table);  
     parser.compile(expression_string, expression); 
    }; 

    double operator()(double x) { 
     symbol_table.get_variable(x_name)->ref() = x; 
     double value = expression.value(); 
     return value; 
    }; 

    std::string x_name; 
    exprtk::symbol_table<double> symbol_table; 
    exprtk::expression<double> expression; 
    exprtk::parser<double> parser; 

}; 

int bits = std::numeric_limits<double>::digits; 

solver_test test_root_finder("(x + 3)(x - 1)^2", "x"); 
std::pair<double, double> r = boost::math::tools::brent_find_minima(test_root_finder, -4., 4./3, bits); 

std::cout.precision(std::numeric_limits<double>::digits10); 
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl; 

Je reçois d'erreur du compilateur C2280 - référence fonction supprimée sur la ligne avec brent_find_minima. Cette erreur se produit également lors de la tentative:

std::pair<double, double> r = boost::math::tools::brent_find_minima(solver_test("(x + 3)(x - 1)^2", "x"), -4., 4./3, bits); 

Comment puis-je passer un foncteur avec un constructeur, sans instancier au préalable?

Si je regarde les messages précédents

How do C++ functor constructors get called when used with for_each or std::transform

Les réponses fournies ne semblent pas être applicables en l'espèce.

Répondre

7

Le problème devient clair si j'essaie

solver_test test_root_finder("(x + 3)(x - 1)^2", "x"); 
solver_test copy_test = test_root_finder; 

Parce que le foncteur n'a pas de constructeur de copie ne peut pas être transmis à l'algorithme comme celui-ci:

std::pair<double, double> r = boost::math::tools::brent_find_minima(test_root_finder, -4., 4./3, bits); 

Ajout

solver_test::solver_test(const solver_test &obj) {}; 

Rend tout OK.