【问题标题】:C++: Return type of std::tie with std::ignoreC++:std::tie 与 std::ignore 的返回类型
【发布时间】:2014-04-10 16:44:09
【问题描述】:

我想知道当某些参数是std::ignore 时,C++11 标准是否对std::tie 返回的std::tuple类型 有任何要求。

更具体地说,我可以假设:

  1. decltype(std::tie(42, std::ignore))decltype(std::tie(std::ignore, 42)) 不一样
  2. decltype(std::tie(42, std::ignore))decltype(std::tie(42)) 不一样
  3. decltype(std::tie(std::ignore, 42))decltype(std::tie(42)) 不一样
  4. decltype(std::tie(std::ignore, std::ignore))decltype(std::tie(std::ignore)) 不一样

换句话说,从类型的角度来看,对于所有按位置匹配std::ignore 的模板参数,生成的元组是否表现为一个类型为decltype(std::ignore) 的元组?

【问题讨论】:

  • 未定义的行为?也许未指定

标签: c++ c++11 stl tuples undefined-behavior


【解决方案1】:

是的,你可以,std::tie 返回一个std::tuple<T&...>,其中T... 是给它的类型。
std::ignore 有一个未指定的类型,但它仍会出现在tuple 中到您在std::tie 中指定的位置。

如果如果让您感觉更好,您可以在代码中的某处添加:

    int n;
    auto i = std::tie(std::ignore, n);
    auto j = std::tie(n, std::ignore);
    auto k = std::tie(n);
    static_assert(!std::is_same<decltype(i), decltype(j)>::value, "");
    static_assert(!std::is_same<decltype(i), decltype(k)>::value, "");
    static_assert(!std::is_same<decltype(j), decltype(k)>::value, "");

对于您明确使用的任何组合,依此类推。如果您的假设无效,这种方式编译将失败。

【讨论】:

  • 所以,只要我不对 std::ignore 的类型做任何假设,我就可以将上面所有的元组视为不同的类型(我需要它们只是为了专业化目的)?此外,使用decltype(std::ignore)&amp;&amp;std::forward 转发std::ignore 是否安全,例如想象一下你是一个std::tuple 的子类?
  • @leden 我不明白你为什么不能转发ignore,但我认为你不能假设你可以将它分配给另一个ignore
  • 三是您的推理自相矛盾,std::ignore 未指定具体意味着标准不要求它与任何其他类型不同;因此std::ignore 成为int 将符合标准(尽管它会很愚蠢)
  • @MatthieuM。这是有道理的,我认为标准可以对未指定的事物进行限制或列出可接受的可能性(它明确表示它可以用于未指定的行为)但它不会为std::ignore 这样做。我不知道您是否可以说它必须不同于任何其他类型,您可以提供 tuple 以便编译器能够将其分离出来。
  • 子类化标准容器通常被认为是一件坏事™。这不是不这样做的唯一原因,但例如,它们没有虚拟析构函数。至于std::ignore,因为类型是未指定的,你不能对它的独特性做出任何假设。它在某些平台上可能是不同的,但在其他平台上却不是。依赖某些行为是不可移植的,并且可能会在你的脸上爆炸。
猜你喜欢
  • 2017-04-16
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多