c++ - 使用模板化类型的模板中的函数原型(prototype)

标签 c++ templates c++11 functional-programming std

我想了解为什么会失败:

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

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

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

谢谢!


编辑:详尽的例子: 基本上,我想做的是为 MapFunction 执行一个特定的原型(prototype)。和 ReductionFunction类型。

我想:

  • MapFunction : typeof(*InputIterator) -> T
  • 归约函数:(T, 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))> map部分,错了,应该是: std::function<T (decltype(*in))> map .

但是这失败了:

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

最佳答案

如果您提供一个显示问题的极简示例,而不是将问题嵌入到大量代码中,从而使问题更难发现,我认为您会更快地得到答案。此外,编辑帖子相当于减少文本,删除不相关的 Material 。据我所见,你想传递 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(值, 0.0, std::function)>(有趣));

当然,这不是很漂亮,所以 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>);

签名仍然需要以一种不会导致它被考虑用于模板参数推导的方式来制定。

关于c++ - 使用模板化类型的模板中的函数原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18372814/

相关文章:

c++ - Visual Studio 2015 C++项目错误C++ 11标准

c++ - 是否可以为不同的 block 静态分配不同的共享内存?

c++ - 缺少 .dll 文件 C++

c++ - 如果不是抽象则调用基类方法

c++ - 将模板函数指针转换为 bool 失败

c++ - 默认创建类 `final`还是给它们一个虚拟的析构函数?

android - CMake 编译器测试在 Android 中找不到包含目录

c++ - 处理将 uint8 自动显示为 int 到 ostream

c++ - MSVC 友元函数声明错误

c++ - 二维阵列反转线中的段错误