gpt4 book ai didi

c++ - std::enable_if 和 std::shared_ptr

转载 作者:行者123 更新时间:2023-11-30 02:39:04 25 4
gpt4 key购买 nike

目标:让函数分派(dispatch)按预期工作。最小的示例代码应该不言而喻。我想支持任务:命名任务,在自己的类中实现,以及更简单的任务,使用 lambda 指定。理想情况下,任何可以转换为 std::function<void (void)> 的东西应该可以。

#include <iostream>
#include <memory>
#include <functional>

// A Base class for my tasks
class BaseTask
{
public:
virtual void blah() = 0;
};

// An important enough tasks that it gets to have its
// own class.
class NamedTask : public BaseTask
{
public:
virtual void blah()
{
std::cout << "Hey !" << std::endl;
}
};

// A wrapper around simpler tasks. (lambda)
class GenericTask : public BaseTask
{
public:
GenericTask(const std::function<void (void)> fct) :
fct_(fct) {}

virtual void blah() override
{
fct_();
}

private:
std::function<void (void)> fct_;
};

void enqueue(std::shared_ptr<BaseTask> t)
{
// store in queue.
// We'll just call it here for the sake of the example
t->blah();
}

template<typename Callable>
//typename std::enable_if<!std::is_base_of<BaseTask, Callable>::value>::type
//typename std::enable_if<!std::is_base_of<std::shared_ptr<BaseTask>, Callable>::value>::type
void enqueue(const Callable &c)
{
auto t = std::make_shared<GenericTask>(c);
t->blah();
}

int main()
{
auto named = std::make_shared<NamedTask>();
enqueue(named); // doesn't compile: tries to call the templated enqueue.

enqueue([] () -> bool { std::cout << "Lamda" << std::endl; });
}

问题:我没能写出正确的 enable_if模板。示例中的注释行是我尝试过的。

  • 第一个不起作用,因为 Callable 的类型是 std::shared_ptr<NamedTask> ,它不是 BaseTask 的 child .
  • 第二个也失败了,大概是因为std::shared_ptr<NamedTask>不源自 std::shared_ptr<BaseTask> .

最佳答案

您有两种情况:您的可调用对象可转换shared_ptr<BaseTask> , 或不。检查碱基不正确 shared_ptr<NamedTask>按类层次结构与 shared_ptr<BaseTask> 无关, 但你可以构造一个 shared_ptr<BaseTask>从中。

即:

// is convertible to shared_ptr<BaseTask>
void enqueue(std::shared_ptr<BaseTask> t);

// is NOT convertible to shared_ptr<BaseTask>
template<typename Callable>
typename std::enable_if<
!std::is_convertible<Callable, std::shared_ptr<BaseTask>>::value
>::type
enqueue(const Callable &c);

或者,您可以将这两种情况视为可构造/不可构造:

template<typename Callable>
typename std::enable_if<
!std::is_constructible<std::shared_ptr<BaseTask>, Callable>::value
>::type
enqueue(const Callable &c);

第三种选择是调节函数模板 enqueue在任何可以用零参数调用的东西上:

template<typename Callable>
auto enqueue(const Callable &c) -> decltype(c(), void())

关于c++ - std::enable_if 和 std::shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30172003/

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