簡體   English   中英

std::tuple 類型到另一個類型

[英]std::tuple types to another ones

如何迭代元組(使用 C++11)? 我嘗試了以下方法:

for(int i=0; istd::tuple_size<T...::value; ++i) std::get(my_tuple).do_sth(); 但這不起作用:

錯誤 1:抱歉,未實現:無法將“Listener...”擴展為固定長度的參數列表。 錯誤 2:i 不能出現在常量表達式中。

那么,我如何正確地迭代元組的元素呢?

使用類似的元 function

template <template <typename> typename Transformer, typename... Ts> 
auto transform_types(std::tuple<Ts...>) -> std::tuple<typename Transformer<Ts>::type...>;

您可以創建一個類型特征,例如

template <template <typename> typename Transformer, typename Tuple>
using transform_types_t = decltype(transform_types<Transformer>(std::declval<Tuple>()));

然后你會像使用它一樣

using transformed_tuple = transform_types_t<Transforming, TUPLE>;

現在transformed_tuple是一個std::tuple<int, float, int, short int, float, float> 你可以在這個活生生的例子中看到它的工作原理

C++模板有一種參數稱為模板模板參數,它是一個模板參數,它本身就是一個模板。 這些類型的參數可用於提供像Transforming<T>這樣的模板。

示例

#include <tuple>

// Original trait
template<typename ...> struct Transforming;
template<typename T> struct Transforming<T> { using type = T; };
template<> struct Transforming<char> { using type = int; };
template<> struct Transforming<long> { using type = int; };
template<> struct Transforming<double> { using type = float; };

// T is a template template parameter
// It is a `class` template which has a single `class` template parameter
// Tuple is the tuple of types to transform
template<template<class> class T, class Tuple>
struct transform_types;

// Specialize for `std::tuple` to extract argument types
template<template<class> class T, class ... A>
struct transform_types<T, std::tuple<A...>>
{
    // Make a new `std::tuple` with the transformed types
    // Expand the parameter pack using the template class `T`
    using type = std::tuple<typename T<A>::type...>;
};

template<template<class> class T, class Tuple>
using transform_types_t = typename transform_types<T, Tuple>::type;

// Demonstration
using input_tuple = std::tuple<int, float, char, short, double, double>;
using transformed = transform_types_t<Transforming, input_tuple>;
using expected = std::tuple<int, float, int, short, float, float>;

#include <type_traits>
static_assert(std::is_same_v<transformed, expected>);

你可以這樣做:

#include <iostream>
#include <type_traits>
#include <tuple>

template<typename ...> struct Transforming;
template<typename T> struct Transforming<T> { using type = T; };
template<> struct Transforming<char> { using type = int; };
template<> struct Transforming<long> { using type = int; };
template<> struct Transforming<double> { using type = float; };

template <template<typename...> class Transform,typename T>
struct Transformed;

template <template<typename...> class Transform,typename...Ts>
struct Transformed<Transform, std::tuple<Ts...>> {
    using type = std::tuple<typename Transform<Ts>::type ...>;
};


int main() {
    using t = std::tuple<char,long,double>;
    using transformed = Transformed<Transforming,t>::type;
    using expected = std::tuple<int,int,float>;
    std::cout << std::is_same_v< transformed,expected>;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM