gpt4 book ai didi

c++ - 采用 lambda 的模板类的类型推导

转载 作者:行者123 更新时间:2023-11-30 01:02:36 28 4
gpt4 key购买 nike

我正在尝试编写一个类,它能够在以后及时调用不带参数的 lambda。我期待 C++17 类模板参数推导以避免需要工厂函数。但是,尝试在不指定类型的情况下实例化对象会失败。我可以很好地使用工厂功能,但我想了解为什么会这样。

我使用的是 VC++2017,启用了 C++17 工具集。这是预期的行为吗?为什么?由于模板函数和模板类的类型推导规则不同,是否可以避免或需要工厂函数?我们将不胜感激。

template <typename F>
class WillInvoke
{
public:
WillInvoke(std::decay_t<F> f) : f(std::move(f)) { }

void CallNow() { f(); }

private:
std::decay_t<F> f;
};

template <typename F>
WillInvoke<F> make_WillInvoke(F && f)
{
return WillInvoke<F>(std::forward<F>(f));
}

int main()
{
// OK
auto w = make_WillInvoke([](){ std::cout << "Hello World"; });
w.CallNow();

// Won't compile
WillInvoke w2([](){ std::cout << "Hello World"; }); // No instance of constructor matches argument list
w2.CallNow();
}

最佳答案

这是因为像 std::decay<T>::type 这样的成员类型别名不可扣除。

template<typename T>
void call_me(std::decay_t<T>) {}

// won't work :(
// call_me(1);

我不认为你的类应该衰减类型。相反,你的类应该声明它需要一个对象类型并将衰减移到 make 函数中:

template <typename F> // requires std::is_object_v<F>
class WillInvoke
{
static_assert(std::is_object_v<F>,
"WillInvoke requires F to be an object type"
);
public:
WillInvoke(F f) : f(std::move(f)) { }

void CallNow() { f(); }

private:
F f;
};

template <typename F>
auto make_WillInvoke(F && f) -> WillInvoke<std::decay_t<F>>
{
return WillInvoke<std::decay_t<F>>(std::forward<F>(f));
}

好的是,在 C++20 中,您可以取消对要求的注释,让编译器在调用站点强制执行它。

关于c++ - 采用 lambda 的模板类的类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55715241/

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