2016-10-12 3 views
6

Ich versuche zu verstehen, warum ein Funktor mit einem Konstruktor nicht an einen Algorithmus übergeben werden kann, während ein Funktor ohne Konstruktor sein kann.Wie konstruiere ich einen Funktor zur Verwendung mit einem Algorithmus wie boost's brent_find_minima?

Für den Algorithmus boost-brent_minima. Der Beispielcode funktioniert gut, wenn der Funktor keinen Konstruktor hat:

#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; 

Allerdings, wenn ich einen Konstruktor verwenden, um eine benutzerdefinierte Funktors wie folgt zu generieren:

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; 

ich Compilerfehler C2280 - Referenz gelöschte Funktion in der Zeile mit brent_find_minima. Dieser Fehler tritt auch bei dem Versuch,:

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

Wie kann ich einen Funktor mit einem Konstruktor übergeben, ohne es vorher zu instanziieren?

Wenn ich bei früheren Posts aussehen

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

Die bereitgestellten Antworten scheinen nicht auf diesen Fall anwendbar zu sein.

Antwort

7

Das Problem wird deutlich, wenn ich

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

versuche Da der Funktors keine Copykonstruktor hat, kann es nicht auf den Algorithmus wie folgt übergeben werden:

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

Hinzufügen

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

Macht alles in Ordnung.

Verwandte Themen