Quiero pasar las funciones binarias estandarizadas de C ++ a una función de plantilla, pero de alguna manera no logré que funcionara.

El siguiente es mi intento de hacerlo:

template<template <typename> typename Pred,typename T, typename Iterator>
void iota_stepa(Iterator begin, Iterator end, T startofSequence_, T threadStep)
{
    int currMaxThreads = startofSequence_;
    bool first = true;
    generate(begin, end,  Pred<T>(currMaxThreads, threadStep) );
}

Y probándolo con:

vector<int> tempVect_(10, 0);

iota_stepa<std::plus>(begin(tempVect_),end(tempVect_),1,thread::hardware_concurrency());

Lamentablemente me da los errores:

Severity    Code    Description Project File    Line    Suppression State
Error   C2440   '<function-style-cast>': cannot convert from 'initializer list' to 'std::plus<int>'
Error   C2672   'generate': no matching overloaded function found   FractalCarpet   
Error   C2780   'void std::generate(_FwdIt,_FwdIt,_Fn0)': expects 3 arguments - 2 provided  FractalCarpet

La salida de la consola se parece a la siguiente:

1>  c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(55): note: see reference to function template instantiation 'void iota_stepa<std::plus,int,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>>(Iterator,Iterator,T,T)' being compiled
1>          with
1>          [
1>              Iterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>,
1>              T=int
1>          ]
1>c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(34): error C2672: 'generate': no matching overloaded function found
1>c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(34): error C2780: 'void std::generate(_FwdIt,_FwdIt,_Fn0)': expects 3 arguments - 2 provided
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(1532): note: see declaration of 'std::generate'

¿Alguien podría ayudarme, cómo solucionar este problema?

2
mbed_dev 15 dic. 2016 a las 16:40

2 respuestas

La mejor respuesta

std::generate necesita un generador, algo que se pueda llamar como gen(). Podrías crear uno con una lambda, quizás así:

template<template <typename> class Pred, typename T, typename Iterator>
void iota_stepa(Iterator begin, Iterator end, T startofSequence_, T threadStep)
{
    bool first = true;
    T current;
    auto gen = [&]() -> T
    {
        if(first) {
            current = startofSequence_;
            first = false;
        } else {
            current = Pred<T>() ( current, threadStep );
        }
        return current;
    };
    generate(begin, end, gen );
}
3
NathanOliver 15 dic. 2016 a las 14:08
Pred<T>(currMaxThreads, threadStep) );

Pred<T> es un tipo. Necesita construir un objeto invocable real:

Pred<T>()(currMaxThreads, threadStep) );

Sin embargo, este no puede ser el último argumento de std::generate. Este último requiere un objeto invocable sin argumentos, presumiblemente con un estado (de lo contrario, una llamada a std :: fill sería suficiente). No está claro cómo una función binaria arbitraria podría adaptarse para cumplir este papel.

0
n. 'pronouns' m. 15 dic. 2016 a las 14:19