c++ - 使用可变参数模板在 C++ 中实现差异化

标签 c++ c++11 templates variadic-functions

我正在尝试在 C++ 中实现除差公式,因为它看起来 here .

到目前为止我已经做到了

template<typename F, typename T>
T divdiff(F f, T t1, T t2) {
  return (f(t1) - f(t2)) / (t1 - t2);
};

template<typename F, typename T, typename... Args>
T divdiff(F f, T tstart, Args... t, T tend) {

  return (divdiff(f, tstart, t...) - divdiff(f, t..., tend))/ (tstart - tend);

};

它编译得很好,但是当它尝试像这样使用它时

 double r = divdiff([](double x) { return 2 * x; }, 1.0, 2.0, 3.0);

我收到以下错误

note: candidate function not viable: requires 3 arguments, but 4 were provided
T divdiff(F f, T tstart, Args... t, T tend) {``

我的编译器是 gcc

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 8.0.0 (clang-800.0.42.1) Target: x86_64-apple-darwin15.4.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin

有谁知道为什么它不起作用以及如何修复它

最佳答案

template<typename F, typename T, typename... Args>
T divdiff(F f, T tstart, Args... t, T tend)

Args... t不在参数列表末尾,则不会被推导。不允许进行此类推导,部分原因是为了简化语言规则,部分原因是为了帮助保持程序简单(并防止搬起石头砸自己的脚)。您可以指定 Args ...明确喜欢 divdiff<F, double, double> ,但是对于递归调用,很难删除最后一个 double .

无论如何,可变参数模板方法都会遭受模板膨胀和效率低下的问题,因为参数列表可能会被每个函数调用复制。由于序列的元素应该都是相同的类型,因此请考虑使用迭代器。然后您可以使用 std::initializer_list 添加便利的重载用于基于数组的可迭代序列。

template< typename F, typename bidirectional_iterator >
typename std::iterator_traits< bidirectional_iterator >::value_type
divdiff( F f, bidirectional_iterator first, bidirectional_iterator last ) {
    bidirectional_iterator next = std::next( first );
    bidirectional_iterator prev = std::prev( last );
    auto diff = next == prev?
        f( * first ) - f( * prev )
      : divdiff( f, first, prev ) - divdiff( f, next, last );
    return diff / ( * first - * prev );
}

template< typename F, typename T >
T divdiff( F f, std::initializer_list< T > il )
    { return divdiff( f, il.begin(), il.end() ); }

Demo .

关于c++ - 使用可变参数模板在 C++ 中实现差异化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41711200/

相关文章:

c++ - 通过 unique_ptr vector 搜索的查找函数的返回值

c++ - std::queue::size() 在 pop() of size() == 0 之后可以返回一个巨大的数字

c++ - 了解模板的声明、定义和特化

c++ - 未解析的重载函数类型

c++ - 如何通用地编写隐藏结构的属性? (C++ 的设计/实现)

c++ - 找不到 vector 使用中的 fatal error

c++ - 在 Eclipse/StatET 中编写包含 C++ 代码的 R 包

c++ - 跳过 list ,他们的表现真的和Pugh Paper所说的一样好吗?

c++ - 在 directx 9 c++ 中应用纹理时出现巨大问题

c++ - 混合术语