Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:生成模板参数?_C++_Templates_Macros - Fatal编程技术网

C++ C++;:生成模板参数?

C++ C++;:生成模板参数?,c++,templates,macros,C++,Templates,Macros,我遇到了一个不幸的情况,我需要编写以下代码: std::map<type1_key, type1_value, type1_cmp> x; std::map<type2_key, type2_value, type2_cmp> y; std::map<type3_key, type3_value, type3_cmp> z; // ... 可以使用以下宏: #define map_type( x ) std::map<x##_key, x##_v

我遇到了一个不幸的情况,我需要编写以下代码:

std::map<type1_key, type1_value, type1_cmp> x;
std::map<type2_key, type2_value, type2_cmp> y;
std::map<type3_key, type3_value, type3_cmp> z;
// ...

可以使用以下宏:

   #define map_type( x ) std::map<x##_key, x##_value, x##_cmp>

我认为宏解决方案更可取,但如果您不希望宏污染全局范围,这里有一个版本可以将信息封装在traits结构中:

#define make_traits(T) \
struct T##_traits { \
  typedef T##_key key; \
  typedef T##_value value; \
  typedef T##_cmp cmp; \
}

make_traits(type1);
make_traits(type2);
make_traits(type3);

#undef make_traits

template<typename T>
using map_type =
  std::map<typename T::key, typename T::value, typename T::cmp>;

map_type<type1_traits> x;
#定义制造特征(T)\
结构T####U特征{\
typedef T###u键\
typedef T###u值\
类型定义T###U cmp\
}
制造_特征(类型1);
制造_特征(类型2);
制造_特征(类型3);
#未定义的make_特性
模板
使用map\u类型=
标准::地图;
map_型x;

我建议更多地使用类型系统

template <std::size_t I>
struct kvc;

template <>
struct kvc<1> {
    using key = type1_key;
    using value = type1_value;
    using cmp = type1_cmp;
};
// Similar for the other types

template <std::size_t I>
using map_type = 
    std::map<typename kvc<I>::key, typename kvc<I>::value, typename kvc<I>::cmp>;
模板
结构kvc;
模板
结构kvc{
使用键=类型1\u键;
使用值=类型1\u值;
使用cmp=类型1\u cmp;
};
//其他类型类似
模板
使用映射类型=
标准::地图;

您可以使用宏自动创建专门化,但这样您可以对键/值/cmp进行更精细的控制,并且(在我看来)会得到更好的错误。

这取决于您,但这听起来是个糟糕的主意。尽量不要用这样的宏来模糊代码,除非你的目的是让它难以阅读。哈!我不知道宏能做到这一点。谢谢只是好奇:为什么你觉得宏解决方案比这个更可取?@JerryJeremiah:它需要更少的代码,而且宏的目的(减少语法重复)是显而易见的。但是,如果我计划将特征类型重用为不仅仅是
map\u type
,我会使用这个解决方案。我发现的一个问题是,如果我定义一个函数模板:
template f(const map\u type&a)
,似乎
f(x)
找不到匹配?我必须明确地写出
f(x)
@MetroWind
T
map\u type
中的所有三种用法都是不可推断的,因此实际上
T
本身是无法推断的。但是您可以执行
模板void f(std::map&)@Quentin我明白了。。。是否有一个地方(在标准中?)记录了哪些情况是可推断和不可推断的?
map_type(type1) x;
#define make_traits(T) \
struct T##_traits { \
  typedef T##_key key; \
  typedef T##_value value; \
  typedef T##_cmp cmp; \
}

make_traits(type1);
make_traits(type2);
make_traits(type3);

#undef make_traits

template<typename T>
using map_type =
  std::map<typename T::key, typename T::value, typename T::cmp>;

map_type<type1_traits> x;
template <std::size_t I>
struct kvc;

template <>
struct kvc<1> {
    using key = type1_key;
    using value = type1_value;
    using cmp = type1_cmp;
};
// Similar for the other types

template <std::size_t I>
using map_type = 
    std::map<typename kvc<I>::key, typename kvc<I>::value, typename kvc<I>::cmp>;