gpt4 book ai didi

c++ - 具有派生的模板化类和智能指针的模板推导

转载 作者:行者123 更新时间:2023-12-03 06:57:41 24 4
gpt4 key购买 nike

假设我有一个模板化基类,以及从中派生的模板化类:

template <typename T>
class Base {};

template <typename T>
class Derived : public Base<T> {};
此外,我有一个函数希望接受指向任何 Base<T>或子类的共享指针,并能够轻松地将 T参数用作其签名的一部分:
template <typename T>
T DoSomething(std::shared_ptr<Base<T>>);
我希望能够使用推导的 T和共享的指向 Base<T>或从其派生的任何内容的调用它:
DoSomething(std::make_shared<Base<T>>());
DoSomething(std::make_shared<Derived<T>>());
当然,后者不起作用,因为类型推导失败。
如何修改 DoSomething的签名以使其起作用?在 BaseDerived不是模板的情况下,我已经看到了很多答案,但是如果我仍然想推断出 T(例如,将其用作返回类型,如上所述),我不确定该怎么做。 。
理想情况下,这将导致在过载解析时指向非派生输入的共享指针(和非共享指针)失败。

最佳答案

您可以在函数中使用模板template参数,然后使用static_assert强制执行您的要求。

#include <memory>
#include <vector>

template <typename T>
class Base {};

template <typename T>
class Derived : public Base<T> {};

template <typename T, template <typename> typename U>
T DoSomething(std::shared_ptr<U<T>>) {
static_assert(std::is_base_of_v<Base<T>, U<T>>, "Requires a std::shared_ptr to Base of class derived from Base");
return T{};
}

int main() {
auto foo = std::make_shared<Derived<int>>();
auto baz = std::make_shared<Base<int>>();
auto bar = std::make_shared<std::vector<int>>();

DoSomething(foo);
DoSomething(baz);
DoSomething(bar); // Fails, std::vector<int> is not derived from Base<int>
}
编辑
如果 DoSomething重载,我们可以使用SFINAE而不是 static_assert禁用它。如下所示。
#include <memory>
#include <vector>

template <typename T>
class Base {};

template <typename T>
class Derived : public Base<T> {};

template <typename T, template <typename> typename U, std::enable_if_t<std::is_base_of_v<Base<T>, U<T>>, int> = 0>
T DoSomething(std::shared_ptr<U<T>>) {
return T{};
}

int main() {
auto foo = std::make_shared<Derived<int>>();
auto baz = std::make_shared<Base<int>>();
auto bar = std::make_shared<std::vector<int>>();

DoSomething(foo);
DoSomething(baz);
DoSomething(bar); // Error, no matching function
}

关于c++ - 具有派生的模板化类和智能指针的模板推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64459722/

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