代码之家  ›  专栏  ›  技术社区  ›  RaisinCrab

std::uniform_int_distribution<std::size_t>是否有未定义的行为?

  •  2
  • RaisinCrab  · 技术社区  · 2 年前

    根据 cppreference documentation on std::uniform_int_distribution ,

    如果[ IntType ]不是以下类型之一: short , int , long , long long , unsigned short , unsigned int , unsigned long 或 unsigned long long 。

    我不确定这是如何适用于 std::size_t -即具有这3个混淆:

    1. 一方面, std::size_t 据我所知,通常是 typedef 的 unsigned 类型。
    2. 然而,我不确定标准是否总是如此。
    3. 我不确定 “如果[ IntType ]不是其中之一:。。。“ 暗示 IntType 必须名义上匹配该列表中的某个内容(类型必须按名称显式地为其中之一),或者它是否可以在结构上匹配(因此typedef与其中之一也被认为是可接受的)。

    是 std::uniform_int_distribution<std::size_t> 未定义的行为?

    1 回复  |  直到 2 年前
        1
  •  3
  •   user17732522    2 年前

    一方面,据我所知,std::size_t通常是该列表中一个无符号类型的typedef。

    是的,通常。

    然而,我不确定标准是否总是如此。

    不,技术上也可以 unsigned char 或实现定义的扩展无符号整数类型。前者对我来说似乎不太可能有意义,我也不知道后者的任何例子。

    我不确定“如果[IntType]不是:…中的一个,则未定义”是否意味着IntType必须名义上匹配该列表中的某个(该类型必须明确地是其中一个,按名称),或者它是否可以在结构上匹配(因此,对其中一个的typedef也被认为是可接受的)。

    这意味着由模板参数命名的类型应该是列出的类型之一。它的命名方式并不相关。模板无论如何都无法检测到。


    在实践中 std::size_t 通常是 unsigned int , unsigned long 和 unsigned long long 。因此,您可以使用 static_assert 为了确保你不是在一些需要额外考虑的异国平台上被编译的,正如@Sheff'sCat在问题下的评论中所建议的那样:

    static_assert(std::is_same_v<std::size_t, unsigned> || std::is_same_v<std::size_t, unsigned long> || std::is_same_v<std::size_t, unsigned long long>);