c – 使用模板化类型的模板中的函数原型

我想了解为什么会失败:

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

(当然,这不是真正的代码).

在g -4.8,我得到“模板参数1无效”.

谢谢 !

编辑:彻底的例子:
基本上,我想要做的是为MapFunction和ReductionFunction类型强制执行特定的原型.

我想要:

> MapFunction:typeof(* InputIterator) – > Ť
> ReduFunction:(T,T) – > Ť

码:

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

编辑2:

我认为std :: function< T(decltype(* InputIterator))>地图部分,是错的,它应该是:
std :: function< T(decltype(* in))>地图.

然而,这失败了:

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

我也试过迭代器特征:

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

但它失败了:

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)'

第三次编辑:

另一个试验,我想我开始越来越近了!

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

失败:

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

这是我的电话:

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>())

最佳答案 如果您提供一个显示问题的极简主义示例,而不是将问题嵌入到相当大量的代码中,使问题更难以查看,我认为您可以更快地得到答案.此外,编辑帖子可以相当于减少文本,删除不相关的材料.就我看到的问题而言,你想传递一个std :: function< Signature>可以使用迭代器提供的值的对象.您尝试的内容基本上等于此(尽管您发布了无关的代码片段,但您没有发布完整的示例):

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);
}

此代码尝试从第二个和第三个参数推导出T.但是,它失败了,因为第三个参数不是预期形式,即它不是std :: function< Signature>.相反,第三个参数的类型是double(*)(std :: complex< T double>).解决方法可能是传递正确类型的参数,这确实与函数模板匹配:

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

当然,这不是太漂亮,使f()比必要使用更难.更好的解决方案是获取隐式转换,而不是让第三个参数参与模板参数推导.最简单的方法是不要直接提到T:

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

使用嵌套在hide_type< T>内的类型导致T不能从第三个参数中推导出来,相反,如果第三个参数与类型不匹配,则可能会尝试隐式转换.最后,使用value_type指定参数时遇到问题.虽然该函数的参数不是真正的问题,但您也可以使用value_type,但是您需要将它与typename一起使用以指示依赖名称value_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>);

签名仍然需要以不会因为模板参数推断而被考虑的方式来制定.

点赞