gpt4 book ai didi

c++ - 如何使用 lambda 在 std::function 参数中推导模板类型?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:37:41 25 4
gpt4 key购买 nike

我有一个 boost::variant 并且我只想在变体是特殊类型时才执行一个仿函数,所以我编写了这个函数:

template<typename T, typename Variant>
void if_init(Variant& opt_variant, std::function<void(T)> functor){
if(auto* ptr = boost::get<T>(&opt_variant)){
functor(*ptr);
}
}

这很好用,但我希望推导出类型 T,这样我就可以这样写:

if_init(b, [](double var){ std::cout << "I'm double and set" << std::endl; });

但是没有推导出类型:

type_inference.cpp:19:5: error: no matching function for call to 'if_init'
if_init(b, [](double var){ std::cout << "I'm double and set" << std::endl; });
^~~~~~~
type_inference.cpp:10:6: note: candidate template ignored: failed template argument deduction
void if_init(Variant& opt_variant, std::function<void(T)> functor){

如果我写:

if_init<double>(b, [](double var){ std::cout << "I'm double and set" << std::endl; });

效果很好。

有没有办法推导出 T 类型?我只想输入一次 T。这里的类型很短,但在实际情况中,有长类型。

我正在使用 CLang 3.2。

这是完整的测试用例(第一个调用编译而不是第二个):

#include <iostream>
#include <functional>
#include <boost/variant.hpp>

typedef boost::variant<int, double> Test;

template<typename T, typename Variant>
void if_init(Variant& opt_variant, std::function<void(T)> functor){
if(auto* ptr = boost::get<T>(&opt_variant)){
functor(*ptr);
}
}

int main(){
Test b = 1.44;

if_init<double>(b, [](double var){ std::cout << "I'm double and set" << std::endl; });
if_init(b, [](int var){ std::cout << "I'm int and set" << std::endl; });

return 0;
}

最佳答案

我建议你想想std::function<Sig>作为任何一个符合 Sig 的仿函数的容器作为签名——并且可以随时替换。此功能非常方便,例如std::vector<std::function<Sig>>因为这样的容器可以容纳不同类型的仿函数。

在你的例子中,因为你只关心一个仿函数,所以你真的不需要 std::function<Sig> 的功能。 .因此,我建议您像这样声明函数模板:

template<typename T, typename Variant, typename Functor>
void if_init(Variant& opt_variant, Functor functor);

如果您担心这不能传达Functor必须符合 void(T)签名请备注std::function<Sig> 不会强制执行:虽然显然您以编译错误告终,但这不是一个好消息。它计划进行更改(也许您的实现也有),但更改为另一种错误。对您的情况仍然没有帮助。

我个人使用模板别名 ( in the template parameter list ) 来记录和强制执行仿函数应符合的内容。这最终看起来像:

// Documents that e.g. long l = std::forward<Functor>(functor)(42.)
// should be a valid expression -- a functor that returns int would
// also be accepted.
// Triggers a hard-error (typically a static_assert with a nice message)
// on violation.
template<typename Functor, Requires<is_callable<Functor, long(double)>>...>
R foo(Functor functor);

// Documents that this function template only participates in overload resolution
// if the functor conforms to the signature.
// Does not trigger a hard-error (necessary by design); if everything goes right
// then another overload should be picked up -- otherwise an error of the kind
// 'no matching overload found' is produced
template<typename Functor, EnableIf<is_callable<Functor, long(double)>>...>
R bar(Functor functor);

至于您的确切问题,C++ 的规则不允许在您的情况下推导模板参数。如果它是一个,那真的不是一个容易解决的“问题”。你可以找到more information对此。

关于c++ - 如何使用 lambda 在 std::function 参数中推导模板类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14784441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com