c++ - 不使用有状态元编程的 C++ 计数类型
问题描述
我正在尝试通过使用宏注册类型来逐步创建类型列表。为此,我想使用我发现的一个技巧来回答另一个问题。精简后的代码如下:
#include <iostream>
#include <type_traits>
#include <utility>
#include <tuple>
#define MAXIMUM_SIZE 100
template <std::size_t N>
struct Index : Index<N - 1> {};
template <>
struct Index<0> {};
std::tuple<> GetTypes(Index<0>) { return {}; }
#define GET_REGISTERED_TYPES \
decltype(GetTypes(std::declval<Index<MAXIMUM_SIZE>>()))
#define REGISTER_TYPE(Type) \
inline decltype(std::tuple_cat( \
std::declval<GET_REGISTERED_TYPES>(), \
std::declval<std::tuple<Type>>())) \
GetTypes(Index<std::tuple_size_v<GET_REGISTERED_TYPES> + 1>) { \
return {}; \
}
REGISTER_TYPE(int)
REGISTER_TYPE(float)
REGISTER_TYPE(char)
REGISTER_TYPE(Index<78>)
int main() {
// true
std::cout << std::boolalpha
<< std::is_same_v<
GET_REGISTERED_TYPES,
std::tuple<int, float, char, Index<78>>>
<< std::endl;
}
这种代码是否被认为可以安全使用,或者它是语言某些晦涩部分的一部分,不应该用于生产。我也没有得到评论所争论的关于有状态元编程的问题。REGISTER_TYPE
宏所做的唯一一件事就是声明一个新的函数重载。这怎么能被认为是状态修改?
为了让这个技巧停止工作,应该对 C++ 选择重载函数的规则进行一些根本性的更改,效果是每个中型程序都会停止编译。我对么?
解决方案
假设您有两个标题:
// foo.h
#ifndef foo_h
#define foo_h
#include "register_type.h"
REGISTER_TYPE(int)
#endif
和
// bar.h
#ifndef bar_h
#define bar_h
#include "register_type.h"
REGISTER_TYPE(double)
#endif
那么这两个来源将有不同的定义GetTypes(std::declval<Index<MAXIMUM_SIZE>>())
:
// a.cpp
#include "foo.h"
#include "bar.h"
inline void test() {
std::cout << std::boolalpha
<< std::is_same_v<
GET_REGISTERED_TYPES,
std::tuple<int, double> // true
<< std::endl;
}
// b.cpp
#include "bar.h" // <--- different order of includes
#include "foo.h"
inline void test() {
std::cout << std::boolalpha
<< std::is_same_v<
GET_REGISTERED_TYPES,
std::tuple<int, double> // false !!
<< std::endl;
}
推荐阅读
- flutter - 在 Flutter 中使用 Provider 依赖
- android - 当 GPS 关闭时,Kotlin allCellInfo 返回 null
- python - Pandas - 用字符串标签替换列表中的 int 值
- python - 是否可以使用 pandas 设置最大字符串长度(如 SQL)
- php - 在 App Engine Standard 上部署 Laravel 6 需要部署的文件过多(超过 10,000 个)
- javascript - 使用 jQuery + FadeOut 更改图像源
- iis - ImageProcessor 图像质量下降
- c# - 如何使用空对象模式实现模型
- python - 如何创建具有默认值的列/如何在 Kusto 上填充具有相同值的列
- python - 在 python 中矢量化太慢?还是quad.integrate?还是我的代码?