【问题标题】:Return a variadic template of tuple返回元组的variadic模板
【发布时间】:2019-12-19 06:43:51
【问题描述】:

我想从 std::vector 中的元素创建一个 std::tuple 并从我的函数中返回它。 std::vector 的大小并不总是三,所以我需要一个函数,可以从三个、四个和更多元素创建 std::tuple 并返回它。

#include <iostream>
#include <tuple>
#include <vector>

template<typename... Args>
std::tuple<Args...> create_tuple(const std::vector<int>& vec) {
    if (vec.size() == 2)
        return std::make_tuple(vec[0], vec[1]);
    else if (vec.size() == 3)
        return std::make_tuple(vec[0], vec[1], vec[2]);
}

int main() {
    std::vector<int> vec{ 0, 1, 2 };
    auto t = create_tuple(vec);
}

目前存在编译错误,我该如何解决?我使用的是 C++11,我不能使用 'auto' 作为从函数返回的值类型。

【问题讨论】:

  • 你为什么想要一个所有相同类型的元组?这就是 std::vectorstd::array 的用途。
  • 你完全误解了模板,忘记了 C++ 的静态类型范式。
  • 你认为你为什么需要这个?也许可以做到(毕竟什么都可以),但是一旦你拥有它,你就会意识到你最终得到了与std::vector 已经提供的完全相同的东西。闻起来像 xy problem
  • 1/ 你不能按照说明进行这项工作,因为create_tuple 的返回类型在编译时是不可知的。 2/ 如果遇到错误,一般应将其包含在问题中。

标签: c++ c++11 templates variadic-templates stdtuple


【解决方案1】:

我想从向量中的元素创建一个元组并从我的函数中返回它。向量的大小并不总是三,所以我需要一个可以从三个、四个和更多元素创建元组并返回它的函数。

简短的回答:你不能。

长答案。

正如 LogicStuff 在评论中所解释的,C++ 是一种静态类型语言。

这意味着,在您的情况下,编译器必须知道 编译时间 create_tuple() 返回的类型。

鉴于返回的类型取决于参数的size(),即已知的运行时,编译器无法选择正确的return语句,因此无法选择正确的返回类型.

换句话说,关键点是函数的主体

if (vec.size() == 2)
    return std::make_tuple(vec[0], vec[1]);
else if (vec.size() == 3)
    return std::make_tuple(vec[0], vec[1], vec[2]);

顺便说一句:如果vec.size() 不同于23(例如1),编译器不知道返回什么。但与 std::make_tuple(vec[0], vec[1])std::make_tuple(vec[0], vec[1], vec[2]) 给出不同且不兼容的类型这一事实相比,这是一个小问题。

因此编译器无法选择函数返回std::tuple&lt;int, int&gt; 还是std::tuple&lt;int, int, int&gt;

这类问题可以从C++17开始部分解决,用if constexpr

if constexpr (vec.size() == 2)
    return std::make_tuple(vec[0], vec[1]);
else constexpr if (vec.size() == 3)
    return std::make_tuple(vec[0], vec[1], vec[2]);
else // ???

if constexpr 也不起作用,因为if constexpr 需要一个必须确定编译时间的测试,而使用vec.size()(其中vecstd::vector)是不可能的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 2020-06-26
    • 2017-11-29
    • 2017-09-13
    相关资源
    最近更新 更多