首页 > 解决方案 > 返回元组的可变参数模板

问题描述

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

#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' 作为从函数返回的值类型。

标签: c++c++11templatesvariadic-templatesstdtuple

解决方案


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

简短的回答:你不能。

长答案。

正如 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()2or不同31例如),编译器不知道返回什么。std::make_tuple(vec[0], vec[1])但与andstd::make_tuple(vec[0], vec[1], vec[2])给出不同且不兼容的类型相比,这是一个小问题。

因此编译器无法选择函数返回 astd::tuple<int, int>还是 a std::tuple<int, int, int>

这类问题可以从 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需要一个必须确定编译时间和 with vec.size()(where vecis a std::vector) 的测试是不可能的。


推荐阅读