gpt4 book ai didi

c++ - 每当成员变量可以由可变参数构造时,有条件地启用构造函数

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

我有一个类foo使用模板参数 Tuple我想提供一个可变参数构造函数来初始化一个成员变量 m_elements类型 Tuple , 每当表达式 m_elements{ static_cast<typename Tuple::value_type>(std::forward<Elements>(elements))... }已定义。

我们可以通过以下方式做到这一点:

template<class Tuple>
struct foo
{
using value_type = typename Tuple::value_type;

template<class... Elements, class U = Tuple,
class = decltype(U{ static_cast<value_type>(std::declval<Elements>())... })>
foo(Elements&&... elements)
: m_elements{ static_cast<value_type>(std::forward<Elements>(elements))... }
{}

Tuple m_elements;
};

现在,这个构造函数是否启用也应该取决于其他一些条件。所以,我需要写一些像

template<class... Elements, class U = Tuple,
class = std::enable_if_t</* some other conditions depending on U */>,
class = decltype(U{ static_cast<value_type>(std::declval<Elements>())... })>

我想根据 std::is_constructible 检查我的第一个条件这样我就可以将这张支票移到 enable_if 中.这可能吗?我试过使用 std::is_constructible_v<U, decltype(static_cast<value_type>(std::declval<Elements>()))...> , 但这似乎并不等同于之前的检查。

例如,foo<bar<3>>{1, 2, 3};

template<std::size_t N>
struct bar
{
using value_type = double;
double data[N];
};

将使用之前的检查进行编译,但使用新的检查会产生错误。

最佳答案

作为Rostislav提到,如果T不是函数类型,std::is_constructible_v<T, Args>true iff 变量定义 T obj(std::declval<Args>()...);是良构的。 bar<1> obj(0.); 中的情况并非如此, 导致 bar<1>没有对应的构造函数。

相比之下,bar1<1> obj{ 0. };是良构的。使用建议Detection Toolkit , 我们可以使用

template<class T, typename... Arguments>
using initializable_t = decltype(T{ std::declval<Arguments>()... });

template<class T, typename... Arguments>
constexpr bool is_initializable_v = is_detected_v<initializable_t, T, Arguments...>;

并将支票更改为

template<class... Elements, class U = Tuple,
class = std::enable_if_t<is_initializable_v<U, decltype(static_cast<value_type>(std::declval<Elements>()))...>>>

我认为这比普通的 decltype 更具可读性方法。

关于c++ - 每当成员变量可以由可变参数构造时,有条件地启用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36845386/

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