Function prototype in a template using a template type

I would like to understand why this fails:

template <class T, class U> T apply(U stuff, std::function<T (U)> function) { return function(stuff); } 

(Of course, this is not real code).

In g ++ - 4.8, I get "template argument 1 is not valid".

Thanks!


Edit: detailed example: Basically, I want to provide a specific prototype of the MapFunction and ReductionFunction types.

I would like to:

  • MapFunction: typeof (* InputIterator) -> T
  • ReductionFunction: (T, T) โ†’ T

the code:

 template <class T, class InputIterator, class ReductionFunction> T mapReduce_n(InputIterator in, unsigned int size, T baseval, std::function<T (decltype(*InputIterator))> map, ReductionFunction reduce) { T val = baseval; #pragma omp parallel { T map_val = baseval; #pragma omp for nowait for (auto i = 0U; i < size; ++i) { map_val = reduce(map_val, map(*(in + i))); } #pragma omp critical val = reduce(val, map_val); } return val; } 

Edit 2:

I think the std::function<T (decltype(*InputIterator))> map is wrong, it should be: std::function<T (decltype(*in))> map .

However, this fails:

 mismatched types 'std::function<T(decltype (* in))>' and 'double (*)(std::complex<double>)' 

I also tried iterator features:

 std::function<T (std::iterator_traits<InputIterator>::value_type)> map 

But he fails:

 type/value mismatch at argument 1 in template parameter list for 'template<class _Signature> class std::function' error: expected a type, got '(T)(std::iterator_traits<_II>::value_type)' 

Third edit:

Another test, I think, I'm starting to get closer!

 std::function<T (typename std::iterator_traits<InputIterator>::value_type)> map 

Failure:

 mismatched types 'std::function<T (typename std::iterator_traits<_II>::value_type)>' and 'double (*)(std::complex<double>)' 

Here is my call:

 MathUtil::mapReduce_n( in, // const std::complex<double> * const conf.spectrumSize(), // unsigned int 0.0, MathUtil::CplxToPower, // double CplxToPower(const std::complex<double> val); std::plus<double>()) 
+4
source share
1 answer

I think that you will get answers faster if you provided a minimalist example showing the problem, rather than embedding the problem in a rather large amount of code, which complicates the task. In addition, editing a message can mean reducing text, removing unnecessary material. As far as I see the problem, you want to pass a std::function<Signature> object that can consume the values โ€‹โ€‹provided by the iterator. What you tried basically boils down to this (you did not post a complete example, although you posted unrelated pieces of code):

 template <typename T, typename Iterator> void f(Iterator it, T value, std::function<T(decltype(*it))> fun); double fun(std::complex<double>); int main() { std::complex<double> values[1]; f(values, 0.0, fun); } 

This code tries to infer T from the second and third arguments. However, it fails because the third argument does not have the expected form, i.e. It is not std::function<Signature> . Instead, the type of the third argument is double(*)(std::complex<T double>) . A workaround may be to pass an argument of the correct type, and this really matches the function template:

f (values, 0.0, std :: function)> (fun));

Of course, this is not too pretty and makes f() more difficult to use than necessary. The best solution is to get an implicit conversion and not accept the third argument in the output of the template argument. The easiest way to do this is to not specify T directly:

 template <typename T> struct hide_type { typedef T type; }; template <typename T, typename Iterator> void f(Iterator it, T , std::function<typename hide_type<T>::type(decltype(*it))>); 

Using the type nested inside hide_type<T> means that T not inferred from the third argument, and implicit conversion is implied instead if the third argument is not of the type. Finally, you are having trouble using value_type to specify an argument. Although the function argument is not a problem, you can use value_type too, but you need to use it with typename to indicate that the dependent name of value_type is a type:

 template <typename T, typename Iterator> void f(Iterator it, T , std::function<typename hide_type<T>::type(typename std::iterator_traits<Iterator>::value_type>); 

The signature still needs to be worded so that it is not taken into account in the derivation of the template argument.

+2
source

Source: https://habr.com/ru/post/1498313/


All Articles