标签: stdtuple

公共基类打破了元组的空基类优化

gcc 4.7.1对元组进行空基类优化,我认为这是一个非常有用的功能.但是,似乎有一个意外的限制:

#include <tuple>
#include <cstdint>
#include <type_traits>
class A { };
class B : public A { std::uint32_t v_; };
class C : public A { };
static_assert(sizeof(B) == 4,                "A has 32 bits.");
static_assert(std::is_empty<C>::value,       "B is empty.");
static_assert(sizeof(std::tuple<B, C>) == 4, "C should be 32 bits.");
Run Code Online (Sandbox Code Playgroud)

在这种情况下,最后一个断言失败,因为元组实际上大于4个字节.有没有办法避免这种情况,而不打破类层次结构?或者我是否必须实现我自己的对实现,以其他方式优化这种情况?

c++ gcc libstdc++ c++11 stdtuple

3
推荐指数
1
解决办法
746
查看次数

"解包"std :: array <T,N>作为函数的参数

这是一个非常好的(不是我的)示例,你可以如何扩展(或"爆炸")元组作为函数的参数:

template<int ...I> struct index_tuple_type {
  template<int N> using append = index_tuple_type<I..., N>;
};

template<int N> struct make_index_impl {
  using type = typename make_index_impl<N-1>::type::template append<N-1>;
};

template<> struct make_index_impl<0> { using type = index_tuple_type<>; };

template<int N> using index_tuple = typename make_index_impl<N>::type;

template <typename I, typename ...Args>
struct func_traits;

template <typename R, int ...I, typename ...Args>
struct func_traits<R, index_tuple_type<I...>, Args...> {
  template <typename TT, typename FT>
  static inline R call(TT &&t, FT &&f) {
    return f(std::get<I>(std::forward<TT>(t))...);
  }
};

template<
  typename …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 stdtuple stdarray

3
推荐指数
1
解决办法
1182
查看次数

如何比较不同长度的元组?

我想写一个比较器,它比较不同长度但具有相同"前缀"的元组.考虑以下情况,我有两个元组.

auto t1 = std::make_tuple(10, "Test1");
auto t2 = std::make_tuple(10, "Test", 3.14);
Run Code Online (Sandbox Code Playgroud)


我想对t1 <t2应用"less",其中只比较两个元组的第一个成员(相同的类型?)而第三个只是省略.可能吗?

c++ tuples c++11 stdtuple

3
推荐指数
1
解决办法
239
查看次数

使用 std::tuple_element 时无效使用不完整类型的问题

下面的代码为 a 实现了一个散列函数,std::tuple然后在我的代码库的不同段中使用 a std::unordered_mapof std::tuples。

// compute hash function recursively through each std::tuple element
template<class Tuple, std::size_t N>
struct tuple_hash_compute {
    static std::size_t hash_compute(const Tuple& t) {
        using type = typename std::tuple_element<N-1, decltype(t)>::type; // OFFENDING LINE
        return tuple_hash_compute<Tuple, N-1>::hash_compute(t)
            + std::hash<type>()(std::get<N-1>(t));
    }
};
// base helper
template<class Tuple>
struct tuple_hash_compute<Tuple, 1> {
    static std::size_t hash_compute(const Tuple& t) {
        using type = typename std::tuple_element<0, decltype(t)>::type; // OFFENDING LINE
        return 51U + std::hash<type>()(std::get<0>(t))*51U;
    }
};
// tuple_hash …
Run Code Online (Sandbox Code Playgroud)

c++ stdtuple c++14 stdhash

3
推荐指数
1
解决办法
2367
查看次数

std :: tie的语法不清楚

我只是读一些关于元组的内容.

现在我不清楚以下语法:

std::tie (myint, std::ignore, mychar) = mytuple;
Run Code Online (Sandbox Code Playgroud)

掌握它的作用并不难,但从语言的角度来看会发生什么?我们以某种方式分配函数的返回值?

c++ stl c++11 stdtuple

3
推荐指数
2
解决办法
242
查看次数

C++14:返回 {} 时元组中的默认值

考虑:

std::tuple<bool, double, int> getTuple()
{
    return {};
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,标准对结果元组中的值有何看法?是否保证例如 bool 总是假的?

c++ stdtuple c++14

3
推荐指数
1
解决办法
150
查看次数

std::apply 应该只适用于 std::tuple 吗?

的函数签名std::apply不会将模板参数限制Tuple为 的特化std::tuple,因此它仍然可以接受定义(godbolt)的类似元组的对象:std::tuple_size_v

#include <tuple>
#include <utility>
#include <array>

int main() {
  std::apply([](int, int) {}, std::array{0, 0});
  std::apply([](int, int) {}, std::pair {0, 0});
  std::apply([](int, int) {}, std::tuple{0, 0});
}
Run Code Online (Sandbox Code Playgroud)

但[tuple.apply]std::apply中的描述是:

tuple20.5.5 使用参数调用函数

这是否意味着应用于std::apply除此之外的对象std::tuple是未定义的行为?

c++ language-lawyer stdtuple c++17 stdapply

3
推荐指数
1
解决办法
303
查看次数

如何将 std::string 打包为 std::tuple&lt;Ts...&gt;

我有一个像这样的参数包

<int, long, string, double>
Run Code Online (Sandbox Code Playgroud)

和一个像这样的字符串

"100 1000 hello 1.0001"
Run Code Online (Sandbox Code Playgroud)

如何解析这些数据并将它们打包到 std::tuple<int, long, string, double>

c++ templates stdstring stdtuple c++20

3
推荐指数
1
解决办法
377
查看次数

什么是用于构造具有数组(C或std :: array)元素的C++元组的单行表达式?

我想要一个有数组元素作为成员的元组.特别是,我希望这个数组元素是2D - 所以任何答案都必须超过1D.我理想的是我可以用初始化列表初始化的东西,例如std::tuple<ARRAY_TYPE, ...>({{0, 1}, {2, 3}}, ...).

看起来这样的元组很难构造,需要手动初始化(即,用于循环等).这是我尝试过的:

std::tuple<int[M][N], ...> - 由于C风格数组的限制,这不起作用.元组本身是一个有效的类型,但初始化需要手动完成(不是在构建时).

std::tuple<std::array<std::array<int, M>, N>, ...>- 我认为这会起作用,但由于某种原因,像std::tuple<std::array<std::array<int, 2>, 2>, ...>({{0, 1}, {2, 3}}, ...)"没有匹配的构造函数错误"的失败.它确实在1D工作.

std::tuple<std::vector<std::vector<int>>, ...>({{0, 1}, {2, 3}}, ...)实际上确实有效,但是这里的矢量似乎有些过分

有什么想法吗?有什么方法可以让C风格的数组工作吗?那将是理想的.

c++ stl c++11 stdtuple stdarray

2
推荐指数
1
解决办法
214
查看次数

如何扩展元组以匹配提供的参数?

我有一个功能(简化逻辑后)采取的形式

std::tuple<font_heap, font_heap> get_font_heaps(std::vector<uint8_t> const& a, std::vector<uint8_t> const& b) {
    return std::make_tuple(get_font_heap_from_data(a), get_font_heap_from_data(b));
}
Run Code Online (Sandbox Code Playgroud)

我想对这个函数进行模板化处理,以便它可以处理用户传入的数据集.

auto [serif, sansserif, monospace] = get_font_heaps(serif_data, sansserif_data, monospace_data);
auto [comic_sans] = get_font_heaps(comic_sans_data);
Run Code Online (Sandbox Code Playgroud)

我开始试图像这样重写逻辑:

template<typename ... FontDatas>
auto get_font_heaps(std::vector<uint8_t> const& data, FontData&& ...datas) {
    if constexpr(sizeof...(FontDatas) == 0) {
        return std::make_tuple(get_font_heap_from_data(data));
    else {
        return std::make_tuple(get_font_heap_from_data(data), get_font_heaps(std::forward<FontDatas>(datas)...);
}
Run Code Online (Sandbox Code Playgroud)

但很明显,即使这个编译,它也不能完全按照我想要的方式执行:它在表单中创建了一个嵌套的元组std::tuple<font_heap, std::tuple<font_heap, std::tuple<font_heap>>>,而我想要的std::tuple<font_heap, font_heap, font_heap>

我怎样才能重写这个逻辑来做我想做的事情?我正在使用MSVC 2017.3,因此我可以访问许多C++ 17功能,但不能访问Fold Expressions(我怀疑它会大大简化逻辑).

c++ c++11 stdtuple c++17

2
推荐指数
1
解决办法
126
查看次数