#c
#c
Вопрос:
Вот мой пример кода, сокращенный по сравнению с оригиналом, и он компилируется на моем Mac:
#include <cmath>
#include <iostream>
#include <random>
#include <string>
#include <vector>
#include <Array>
class ranker {};
namespace detail {
template <class T>
struct unique_if
{
using single_object = std::unique_ptr<T>;
};
template <class T>
struct unique_if<T[]>
{
using unknown_bound = std::unique_ptr<T[]>;
};
}
/**
* Constructs a unique ptr in place.
* @param args The parameters to the constructor
* @return a unique_ptr<T>
*/
template <class T, class... Args>
typename detail::unique_if<T>::single_object make_unique(Argsamp;amp;... args)
{
return std::unique_ptr<T>{new T(std::forward<Args>(args)...)};
}
template <class T>
typename detail::unique_if<T>::unknown_bound make_unique(std::size_t size)
{
return std::unique_ptr<T>{new typename std::remove_extent<T>::type[size]()};
}
class MPtf2ln_ranker {
private: // Change the parameters to suit your ranking function
double lambda_ = 0;
double alpha_ = 0;
double s_ = 0;
double mu_ = 0;
public:
MPtf2ln_ranker(); // Default Constructor
MPtf2ln_ranker(double lambda, double alpha, double s, double mu); // Constructor
void set_param(double lambda, double alpha, double s, double mu) {
lambda_ = lambda; alpha_ = alpha; s_ = s; mu_ = mu;
}; // Sets the parameters
// Calculates the score for one matched term
double score_one();
};//MPtf2ln_ranker CLASS
MPtf2ln_ranker::MPtf2ln_ranker(){}//MPtf2ln_ranker()
MPtf2ln_ranker::MPtf2ln_ranker(double lambda, double alpha, double s, double mu)
: lambda_{lambda}, alpha_{alpha}, s_{s}, mu_{mu} {
}//MPtf2ln_ranker()
double MPtf2ln_ranker::score_one() {
return 1.1;
}//score_one()
void tune( ) {
std::array<double,11> lambdaValues {{ 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 }};
std::array<double,11> alphaValues {{ 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 }};
std::array<double,11> sValues {{ 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 }};
std::array<double,10> muValues {{ 0.0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500 }};
auto ranker = make_unique<MPtf2ln_ranker>();
std::size_t s, m, l, a;
s = 0; m=0; l=0; a=0;
ranker->set_param( lambdaValues[l], alphaValues[a], sValues[s], muValues[m]);
}
int main(int argc, char* argv[]) {
auto ranker = make_unique<MPtf2ln_ranker>();
tune();
return 0;
}
В main() ранкер должен быть передан функции tune() . В функции tune () я хочу закомментировать ее переменную автоматического ранкера и использовать ту, которая передается. Это позволило бы tune() обрабатывать несколько ранжировщиков и не дублировать мой код.
Надеюсь, кто-нибудь захочет рассказать мне, как это сделать. Спасибо
Комментарии:
1. Вы
ranker
всегда должны быть типаMPtf2ln_ranker
? Или это должен быть любой объект, у которого есть методset_param
.2. @t.niese На самом деле MPtf2ln_ranker наследует от meta::index::ranker. Я хочу, чтобы функция tune могла обрабатывать два отдельных класса, оба наследуются от meta::index::ranker . Когда я пытаюсь предложить, кажется, что оно указывает на meta::index:ranker, у которого есть этот метод. Этот метод существует только в дочерних классах.
3. Фактический вызов для создания указателя выглядит следующим образом: std::unique_ptr<ранкер>make_ranker<MPtf2ln_ranker>
Ответ №1:
Вы можете использовать шаблон
template <typename T>
void tune(unique_ptr<T>amp; p) { /* ... */ }
[...]
tune(ranker);