gpt4 book ai didi

C++:如何从 make_shared 部分推导出模板参数

转载 作者:行者123 更新时间:2023-12-02 10:06:44 27 4
gpt4 key购买 nike

为了规避restriction on partially supplied explicit template arguments ,我将要从中推导出类模板参数 ( Internal ) 的结构嵌​​入到第二个结构 ( Container ) 中。

我想让代码的用户能够创建例如结果类型的共享指针。通过写我自己的 create结构中的函数,这很好用。

#include <memory>

/// Container that is used in order to partially specify template arguments
template <int A> struct Container {

/// Contained type, of which the template arguments are deduced.
template <int B> struct Internal {
explicit Internal(std::integral_constant<int, B> fu) { (void)fu; }
};

/// Helper function
template <int C>
[[nodiscard]] static auto create(std::integral_constant<int, C> t) noexcept {
return std::make_shared<Container<A>::Internal<C>>(t);
}
};


int main() {
Container<1>::Internal works{std::integral_constant<int, 8>{}};
auto const worksAswell = Container<1>::create(std::integral_constant<int, 8>{});
}

但是当我尝试直接使用 make_shared 时,它失败了。我想让用户使用例如std::make_shared 函数。

int main() {
auto const fails = std::make_shared<Container<1>::Internal>(std::integral_constant<int, 8>{});
}

据我所知,这失败了,因为我无法部分指定模板参数,如果我不想指定所有模板参数,我也无法从 make_shared 函数中推断出它们。


main.cc: In function ‘int main()’:
main.cc:21:74: error: no matching function for call to ‘make_shared<1>(std::integral_constant<int, 8>)’
21 | auto const fails = std::make_shared<1>(std::integral_constant<int, 8>{});
| ^
In file included from /usr/include/c++/9.2.0/memory:81,
from /home/juli/main9.cc:1:
/usr/include/c++/9.2.0/bits/shared_ptr.h:714:5: note: candidate: ‘template<class _Tp, class ... _Args> std::shared_ptr<_Tp> std::make_shared(_Args&& ...)’
714 | make_shared(_Args&&... __args)
| ^~~~~~~~~~~
/usr/include/c++/9.2.0/bits/shared_ptr.h:714:5: note: template argument deduction/substitution failed:

是否可以启用生成器功能,如 std::make_shared部分推导出这样的模板参数?完整代码可以在 here找到.

最佳答案

如果您创建自己的 make_shared接受我们可以使用的模板模板参数 decltype推导出结果类型并将其传递给 std::make_shared .

#include <memory>
#include <type_traits>

/// Container that is used in order to partially specify template arguments
template <int A> struct Container {

/// Contained type, of which the template arguments are deduced.
template <int B> struct Internal {
explicit Internal(std::integral_constant<int, B> fu) { (void)fu; }
};
};

template <template <int> typename partial, typename... Args>
auto make_shared(Args&&... args) {
using target_type = std::remove_pointer_t<decltype(new partial{std::declval<Args>()...})>;
return std::make_shared<target_type>(std::forward<Args>(args)...);
}

using std::make_shared;

int main() {
auto const fails = make_shared<Container<1>::Internal>(std::integral_constant<int, 8>{});
static_assert(std::is_same_v<const std::shared_ptr<Container<1>::Internal<8>>, decltype(fails)>);
}

这里唯一的问题是我们的 make_shared需要知道预期目标的模板签名。

从积极的方面来说,我们可以为不同的模板签名添加多个重载,并且我们可以使用一个参数包。

关于C++:如何从 make_shared 部分推导出模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59886167/

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