提取 C++ 模板参数

2021-12-13 00:00:00 templates c++ rtti

虽然我很怀疑,但我很好奇是否可以从现有类型中提取原始类型模板参数,也许使用 RTTI.

Although I'm doubtful, I'm curious as to whether it's possible to extract primitive-type template parameters from an existing type, perhaps using RTTI.

例如:

typedef std::bitset<16> WordSet;

是否可以在不将其硬编码到其他地方的情况下提取上述代码中的数字 16?欢迎使用特定于编译器的实现,但我对 g++ 特别感兴趣.

Would it be possible to extract the number 16 in the above code without hard-coding it elsewhere? Compiler specific implementations are welcome, though I'm particularly interested in g++.

推荐答案

通常不可能选择任意模板参数.

It's not possible in general to pick arbitrary template parameters.

但是,通常的做法是这样的:

However, the usual way you do it is this:

template<int N>
struct foo {
    static const int value = N;
};

和类型

template<typename T>
struct foo {
    typedef T type;
};

然后您可以通过 foo<39>::valuefoo::type 访问它.

You can access it then as foo<39>::value or foo<int>::type.

如果你有一个特定的类型,你可以使用部分模板特化:

If you have a particular type, you can use partial template specialization:

template<typename>
struct steal_it;

template<std::size_t N>
struct steal_it< std::bitset<N> > {
    static const std::size_t value = N;
};

事实上,同样的原则也适用于类型参数.现在您可以将任何位集传递给它,例如 steal_it<std::bitset<16>>::value(注意使用 size_t,而不是 int!).因为我们还没有可变参数 many 模板参数,我们必须将自己限制在一个特定的参数计数,并为从 1 到 N 的计数重复steal_it 模板特化.另一个困难是扫描具有混合参数的类型(类型和非-类型参数).这可能很难解决.

The same principle is possible for type parameters too, indeed. Now you can pass any bitset to it, like steal_it< std::bitset<16> >::value (note to use size_t, not int!). Because we have no variadic many template paramters yet, we have to limit ourself to a particular parameter count, and repeat the steal_it template specializations for count from 1 up to N. Another difficulty is to scan types that have mixed parameters (types and non-types parameters). This is probably nontrivial to solve.

如果你没有类型,而只有它的一个对象,你可以使用一个技巧,在编译时仍然获得一个值:

If you have not the type, but only an object of it, you can use a trick, to still get a value at compile time:

template<typename T>
char (& getN(T const &) )[steal_it<T>::value];  

int main() {
    std::bitset<16> b;
    sizeof getN(b); // assuming you don't know the type, you can use the object
}

诀窍是让函数模板自动推断类型,然后返回对字符数组的引用.函数不需要定义,唯一需要的是它的类型.

The trick is to make the function template auto-deduce the type, and then return a reference to a character array. The function doesn't need to be defined, the only thing needed is its type.

相关文章