C++类型漏洞解释

标签 c++ c++14

愚蠢的问题。谁能向我解释一下这段代码是如何工作的? (从这里 https://alexpolt.github.io/type-loophole.html )

#include <string>
#include <type_traits>

template<int N> struct tag{};

template<typename T, int N>
struct loophole_t {
  friend auto loophole(tag<N>) { return T{}; };
};

auto loophole(tag<0>);

int main() {

sizeof( loophole_t<std::string, 0> );
    
static_assert(std::is_same< std::string, decltype( loophole(tag<0>{}) ) >::value);

}
它看起来像 sizeof( loophole_t<std::string, 0> );影响编译器全局状态。我的意思是如果我们删除这一行 static_asserts失败。在 C++ 中允许吗?
更新:
刚刚意识到这取决于编译器甚至编译器版本。
适用于任何 GCC >=8(可能也适用于旧版本)。
不能用 clang >= 10 编译,但在 clang 7.0 下工作正常
所以我想说我真正的问题是编译器错误还是标准行为?

最佳答案

它导致模板特化的实例化 loophole_t<std::string, 0> .
作为带有 friend 的类模板函数(记住, friend 不是成员),即 also brings the function into scope在全局命名空间中。
该函数可以拼写为 std::string loophole(tag<0> unusedParam); .
除了扔掉之外,它不直接用于任何其他用途 sizeof在那之后,除了用 decltype“检索”它的返回类型。并将其与 std::string 进行比较在静态断言中(通过演示,预计会通过)。
作者已“收藏”std::string在表达式 tag<0> 中.有点。
如果你写了更多:

sizeof( loophole_t<std::string, 0> );
sizeof( loophole_t<int, 1> );
sizeof( loophole_t<char, 2> );
......你最终会在范围内得到一大堆函数,它们可以拼写:
std::string loophole(tag<0> unusedParam);
int loophole(tag<1> unusedParam);
char loophole(tag<2> unusedParam);
……现在你可以看到函数声明为每个标签“存储”了一个类型。我们可以使用标签“访问”类型:
decltype(loophole(tag<0>{})) thisIsAString = "lol";
decltype(loophole(tag<1>{})) thisIsAnInt = 42;
decltype(loophole(tag<2>{})) thisIsAChar = '!';
这有什么实际好处,我不知道。但是,如果您对此感到绝望,则可以:
using MyTypes = std::tuple<std::string, int, char>;
...然后使用 somewhat more idiomatic means to extract type N .

关于C++类型漏洞解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65190015/

相关文章:

c++ - Qt - 具有枚举类类型的 Q_DECLARE_METATYPE()

c++ - std::errc,如何在 retval 中指示成功

c++ - 如何在 constexpr 函数内部的字符串文字上静态断言条件?

c++ - 如何从通用 lambda 中的可变参数包中获取类型?

c++ - 依靠确定性销毁,避免返回时销毁

c++ - 为什么 std::string 没有标准定义的文字后缀?

c++ - 如何使用不区分大小写的 unicode 字符串作为键的 hash_map?

c++ - 如何混合 32 位整数?或 : Why is there no _mm256_blendv_epi32?

c++ - 无法显示世界中的顶点

c++ - 为什么我们需要 unique_ptr vector 的移动构造函数?