c++ 如何将std::sqrt作为参数传递

ecr0jaav  于 2023-04-01  发布在  其他
关注(0)|答案(3)|浏览(176)

我试图创建一个泛型函数Foo,它将接受一个参数和Op将应用于它的内容。

template <template<class> class Op>   
float foo(float boo) {
    return Op(boo);
}

template <template<class> class Op>   
float foo(float a, float b) {
    return Op(a, b);
}

void caller() {
    float boo = 2.3;
    auto res1 = foo<std::plus>(boo, boo); // works
    auto res2 = foo<std::sqrt>(boo); // fail. error: no instance of overloaded function.
    auto res3 = foo<std::exp>(boo); // fail. error: no instance of overloaded function
}

我认为std::sqrt是相关的
“一组重载或函数模板,接受任何整型的参数.“
std::plus
用于执行加法的函数对象。
如何将std::sqrtstd::exp传递给foo

jv2fixgn

jv2fixgn1#

正如您所指出的,问题在于您的模板需要一个 type(因为这就是您编写它的方式),尽管std::plus是一个类型(一个函子),但std::sqrt是一个函数。
很难为您的问题给予具体的解决方案,因为您从未展示过Op的用法。
但是,一般来说,使用auto模板参数很容易做到:

template <auto Op>
float foo(const float boo) {
    return Op(boo);
}

如果你的C++版本太旧,你需要添加一个接受函数指针的版本。

yqkkidmi

yqkkidmi2#

std::sqrt是一个重载函数,而不是类型。一个简单的解决方法是编写一个泛型lambda来 Package std::sqrt,然后在调用foo时使用它的类型,如下所示:

auto sqrt = [](auto n) { return std::sqrt(n); };
auto res2 = foo<decltype(sqrt)>(boo); // ok

你可以对std::exp做同样的事情。
这是否是一个好的修复取决于您希望如何使用Op参数,这在问题中并不清楚。

c90pui9n

c90pui9n3#

不能将重载集作为模板参数传递。一个简单的解决方法是将sqrtexp Package 到带有模板化operator()的函子中:

struct Sqrt {
    template<class T>
    T operator()(T t) const { return std::sqrt(t); }
};

struct Exp {
    template<class T>
    T operator()(T t) const { return std::exp(t); }
};

那么下面的就行了

auto res2 = foo<Sqrt>(boo);
    auto res3 = foo<Exp>(boo);

相关问题