【问题标题】:Partial Constructor arguments from tuple元组的部分构造函数参数
【发布时间】:2022-01-13 07:51:29
【问题描述】:

在 C++17 中有 std::make_from_tuple;但是,这只适用于存储在元组中的元素数量与构造函数的数量匹配的情况。

我能够连接两个元组并使用std::make_from_tuple

#include <iostream>
#include <utility>
#include <tuple>

class ConstructMe{
public:
  ConstructMe(int a_, int b_, int c_)
  : a(a_), b(b_), c(c_) { }

private:
  int a;
  int b, c;
};

int main(){
  int a = 1;
  std::tuple<int, int> part = std::make_tuple(2,3);
  ConstructMe please = std::make_from_tuple<ConstructMe>(
    std::tuple_cat(std::make_tuple(a), part)
  );
  return 0;
}

经过一些研究(this question 我能够使其与引用以及std::tie 一起使用。

#include <iostream>
#include <utility>
#include <tuple>

class ConstructMe{
public:
  ConstructMe(int& a_, int b_, int c_)
  : a(a_), b(b_), c(c_) { }

private:
  int& a;
  int b, c;
};

int main(){
  int a = 1;
  std::tuple<int, int> part = std::make_tuple(2,3);
  ConstructMe please = std::make_from_tuple<ConstructMe>(
    std::tuple_cat(std::tie(a), part)
  );
  return 0;
}

有没有不需要 c++17 的更简单的方法(例如 std::bind)?

【问题讨论】:

  • 如果您标记问题 C++17,它是关于在 C++17 中实现某些东西。但是您似乎想在旧版本中实现它:将其标记为您正在使用的版本。 std::tie 已经在 C++14 中了。您提到的许多自 C++11 以来的元组内容。
  • std::make_from_tuple 是一个 c++17 特性
  • 您只是在谈论make_form_tuple 的问题并不清楚,并且仍然:您想在另一个版本中实现它。所以标记你想要的版本。顺便说一句,make_from_tuple 是一个库功能,而不是语言功能,您可以随时根据标准化实现自己的实现。
  • 我根据您的建议删除了 c++17 标签,因为这不是我想在 c++17 中实现的。但是我不想为这个问题设定一个确切的标准。

标签: c++ pass-by-reference stdtuple


【解决方案1】:

std::bind 做了完全不同的事情。引用cppreference

函数模板bindf 生成一个转发调用包装器。调用此包装器等效于调用 f 并将其一些参数绑定到 args

您可以只使用 cpp 参考链接来构建您自己的标准化函数实现,例如在 C++14 中

#include <iostream>
#include <utility>
#include <tuple>

namespace detail {
template <class T, class Tuple, std::size_t... I>
constexpr T make_from_tuple_impl( Tuple&& t, std::index_sequence<I...> )
{
    static_assert(std::is_constructible<T,
        decltype(std::get<I>(std::declval<Tuple>()))...>::value);
    return T(std::get<I>(std::forward<Tuple>(t))...);
}
} // namespace detail
 
template <class T, class Tuple>
constexpr T make_from_tuple( Tuple&& t )
{
    return detail::make_from_tuple_impl<T>(std::forward<Tuple>(t),
        std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}

class ConstructMe{
public:
  ConstructMe(int& a_, int b_, int c_)
  : a(a_), b(b_), c(c_) { }

private:
  int& a;
  int b, c;
};

int main(){
  int a = 1;
  std::tuple<int, int> part = std::make_tuple(2,3);
  ConstructMe please = make_from_tuple<ConstructMe>(
    std::tuple_cat(std::tie(a), part)
  );
}

如果要返回更多语言版本,则必须手动执行更多操作。会越来越难,特别是如果你想在 C++11 之前...

【讨论】:

  • 谢谢,很好的回答!似乎没有什么黑魔法,而且实施是标准的一部分,这是有充分理由的。
猜你喜欢
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 2018-10-03
  • 2016-03-11
相关资源
最近更新 更多