【发布时间】:2022-02-06 03:55:28
【问题描述】:
为了避免 XY,我将首先解释我的总体目标。
我试图在编译时在两个不同的通用容器之间做出选择。我提出的解决方案使用宏非常简单。为了演示,这里是 std::vector 和 std::set 的外观(实际上它们是其他容器,但与问题无关)
// switch between the container types
//#define CONT_SET
#ifdef CONT_SET
#define CONTAINER(type) std::set<type>
#else
#define CONTAINER(type) std::vector<type>
#endif
int main() {
CONTAINER(float) cont;
}
这工作得很好。
例如,当我尝试在容器中存储更复杂的类型时,就会出现问题
CONTAINER(std::pair<int, int>) cont;
这不起作用,因为编译器将其检测为两个不同的宏参数std::pair<int 和int>。
我尝试通过添加将整个类型组合在一起的括号来克服这个问题
CONTAINER((std::pair<int, int>)) cont;
然后我得到一个“模板参数 1 无效”(godbolt)
有没有办法告诉编译器整个表达式只是一个宏参数?或者括号中的模板参数是一个有效的类型?
【问题讨论】:
-
分别是
using、typedef别名呢?可能需要template。 -
对于 XY 部分:不需要为此使用宏。您可以简单地使用类型别名。你还想问宏问题还是没有宏的替代方案?
-
你可以简单地使用
#define CONTAINER(...) std::set<__VA_ARGS__> -
为什么不直接
template<class T> using XXX = std::conditional_t<xxx, std::vector<T>, std::set<T>>? -
@πάνταῥεῖ 问题是宏通过文件泄漏。我知道通常它被认为是宏的一个可怕方面,但在这种情况下它是一个优势。我正在尝试提供一个库,其中标头的使用者可以选择在整个库中全局设置或取消设置此开关,我不知道有什么方法可以让
usings 像那样工作跨度>
标签: c++ templates macros preprocessor