c++ - C++类型漏洞解释
问题描述
愚蠢的问题。谁能向我解释一下这段代码是如何工作的?(从这里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++ 允许使用 at 吗?
更新:刚刚意识到它取决于编译器甚至编译器版本。适用于任何 >=8 的 GCC(可能也适用于旧版本)。不使用 clang >= 10 编译,但使用 clang 7.0 可以正常工作
所以我会说我真正的问题是编译器错误还是标准行为?
解决方案
它会导致模板专业化的实例化loophole_t<std::string, 0>
。
作为具有friend
函数的类模板(请记住,friend
s 不是成员),这也将函数带入全局命名空间的范围内。
那个函数可以拼写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>;
…然后使用更惯用的方法来提取类型N。
推荐阅读
- javascript - 如何为 nunjucks 和 node js 应用程序构建 jQuery?
- composer-php - 试图在 goormide 上安装作曲家
- reporting-services - 如何在 SSRS 中添加回车/换行
- c++ - 如何编译 CUDA C++ 项目
- wordpress - 向 Wordpress 插件的类函数添加过滤器
- c# - 带有两个 select 和 where 条件的 Linq 语句
- python - 用于通信 python - C++ 的 UNIX 套接字
- ios - pod FBSDKCoreKit 的 react-native-fbsdk 问题
- angular - Angular:从列表中链接两个不同的复选框
- graphql - Graphql 突变与 aws-appsync 上的父对象和子数组