2016-06-13 8 views
-1

Ich habe folgende Frage zu std :: experimental :: apply. Von dem, was ich verstehe, nimmt es Funktionsobjekt und Tupel, und dann erweitert das Tupel in Parameter Pack, die auf bestimmte Funktor angewendet wird. Unglücklicherweise habe ich im folgenden Code keine Übereinstimmung, wenn ich versuche zu kompilieren (Funktionsaufruf).C++ Parameterpack aus Tupel über std :: experimental :: apply Funktion

Hier ist mein Testfall (sollte gut kompilieren ohne experimentell :: anwenden).

#include<utility> 
#include<iostream> 
#include"optimalization.hpp" 

class Function{ 
    public: 
     Function()=default; 
     double operator()(double x, double y, double z){ 
      return (std::exp(x+1.25)*std::pow(y,z))/std::exp((x*y)/z); 
     } 
}; 

int main(){ 
    Function f{}; 
    double x=optimize<100, 200>(f, std::make_pair(-21, 37), std::make_pair(22.5, 88.11), std::make_pair(-13, 37)); 
    std::cout << x << std::endl; 

} 
+0

Korrigieren Sie die Formatierung Ihres Codes. –

Antwort

1

Der Kern des Problems ist, dass Function::operator() nicht const ist. Es gibt einige andere Probleme, wie zum Beispiel constexpr auto optimize(Func function, const std::pair<auto, auto>... range), die ungültige Syntax ist, aber diese fallen im Grunde, sobald das Hauptproblem behoben ist.

Arbeitscode:

#include <cstddef> 
#include <functional> 
#include <random> 
#include <experimental/tuple> 
#include <type_traits> 
#include <utility> 

template< 
    std::size_t population_size, std::size_t generations, 
    typename Func, 
    typename Compare = std::greater<>, 
    typename Generator = std::default_random_engine, 
    typename Distribution = std::uniform_real_distribution<>, 
    typename... RangeElemT 
> 
auto optimize(Func function, std::pair<RangeElemT, RangeElemT> const... range) { 
    static_assert(sizeof...(range) > 2, "Function needs at least two arguments"); 

    auto generate_number = [&](auto range) { 
     static_assert(
      std::is_arithmetic<std::tuple_element_t<0, decltype(range)>>{}, 
      "First argument of std::pair has to be arithmetic!" 
     ); 
     static_assert(
      std::is_arithmetic<std::tuple_element_t<1, decltype(range)>>{}, 
      "Second argument of std::pair has to be arithmetic!" 
     ); 

     return std::bind(Distribution(range.first, range.second), Generator{}); 
    }; 

    auto genotype = std::make_tuple(generate_number(range)()...); 
    auto key = std::experimental::apply(function, genotype); 
    return std::make_pair(key, genotype); 
} 

#include <cmath> 

struct Function { 
    double operator()(double x, double y, double z) const { 
     return std::exp(x + 1.25) * std::pow(y, z)/std::exp(x * y/z); 
    } 
}; 

#include <iostream> 
#include <boost/type_index.hpp> 

int main() { 
    namespace bti = boost::typeindex; 

    Function f{}; 
    auto x = optimize<100, 200>(
     f, 
     std::make_pair(-21, 37), 
     std::make_pair(22.5, 88.11), 
     std::make_pair(-13, 37) 
    ); 
    std::cout 
     << bti::type_id_with_cvr<decltype(x)>().pretty_name() << '\n' 
     << x.first << " :: " 
     << std::get<0>(x.second) << ", " 
     << std::get<1>(x.second) << ", " 
     << std::get<2>(x.second) << '\n'; 
} 

Online Demo

Beachten Sie auch, dass Sie in beiden Orten verwendet decltype(auto), auto (und aus Gründen der Klarheit sollte) stattdessen verwendet werden.

+0

Ja, mein Schlechter, danke für Ihre Eingabe, es war viel zu spät in der Nacht, um Fragen zu StackOverflow zu stellen, Grüße. – MostLovelyRollOnThePlanet