我有一些深度C ++ 11可变参数模板的魔术用法代码。我使用专门的类来识别模板树的部分,我命名为“标签”。每个标签都有唯一的编号标识符 我需要找到一种方法来访问标签的标识符
以下是一些小例子:
#include <string>
#include <iostream>
template <unsigned long ID, typename PARAM>
class tag_
{
//getter for ID. Better to exclude it. If possible - move to external helper
constexpr static unsigned long get_id() {return ID;}
//PARAM is used in some functions of this class
};
//tag's declarations for future usage
template<typename PARAM>
using tag1 = tag_<1UL, PARAM>;
template<typename PARAM>
using tag2 = tag_<2UL, PARAM>;
template<typename PARAM>
using tag3 = tag_<3UL, PARAM>;
//helper class that can iterate TAGS
template <template<typename> class... TAGS>
struct helper
{};
template <template<typename> class TAG>
struct helper<TAG>
{
static void print_tag(std::ostream& out)
{
out << std::string("Tag");
out << TAG::get_id(); // Here I can't call: error: 'template<class> class TAG' used without template parameters
}
};
template <template<typename> class TAG, template<typename> class... TAGS>
struct helper<TAG, TAGS...>
{
static void print_tag(std::ostream& out)
{
out << std::string("Tag");
out << TAG::get_id(); // Here I can't call: error: 'template<class> class TAG' used without template parameters
out << std::string(", ");
helper<TAGS...>::print_tag(out);
}
};
//this class uses tags for some processing
template <template<typename> class... TAG_LIST>
class tagged
{
public:
void test1(std::ostream& out)
{
out << std::string("This function works good");
}
void test2(std::ostream& out)
{
helper<TAG_LIST...>::print_tag(out);
}
};
// this class is re-defined for some types of T
template<typename T, typename PARAM>
class usage
{
public:
void test1(std::ostream& out)
{
details.test1(out);
}
void test2(std::ostream& out)
{
details.test2(out);
}
T details;
PARAM params;
};
//endpoint
struct finish{};
//definition for future usage
template<template<typename> class T1, template<typename> class T2, template<typename> class T3, typename PARAM>
using multitag = usage<tagged<T1, T2, T3>, PARAM>;
int main(int argc, const char* argv[])
{
// this way I am construction my objects tree
multitag<tag1, tag2, tag3, tag1<tag2<tag3<finish>>>> tmp;
tmp.test1(std::cout); // ok
std::cout << std::endl;
tmp.test2(std::cout); //compile error. I want to get "Tag1, Tag2, Tag3" printed
std::cout << std::endl;
}
答案 0 :(得分:2)
multitag<tag1, tag2, tag3, tag1<tag2<tag3<finish>>>> tmp;
这是您对tmp
的定义,您只需传入tag1
,这是一个模板类型别名
template<typename PARAM>
using tag1 = tag_<1UL, PARAM>;
但是未提供其模板参数PARAM
。
所以当你想要使用它时,
out << TAG::get_id()
你应该给它一个参数,例如
out << TAG<dummy>::get_id();
dummy
可以是任何内容,例如
class dummy{};
答案 1 :(得分:1)
最接近的是为每个tagX
声明一个专门化:
template <template <typename> class TAG> struct tag_id;
template <> struct tag_id<tag1> : std::integral_constant<unsigned long, 1UL> {};
template <> struct tag_id<tag2> : std::integral_constant<unsigned long, 2UL> {};
template <> struct tag_id<tag3> : std::integral_constant<unsigned long, 3UL> {};
out << tag_id<TAG>{};