Joh*_*itb 42
这是不可能的.通常的做法是:
template<int N>
struct foo {
static const int value = N;
};
Run Code Online (Sandbox Code Playgroud)
和类型
template<typename T>
struct foo {
typedef T type;
};
Run Code Online (Sandbox Code Playgroud)
您可以将其作为foo<39>::value或访问foo<int>::type.
如果您有特定类型,则可以使用部分模板专业化:
template<typename>
struct steal_it;
template<std::size_t N>
struct steal_it< std::bitset<N> > {
static const std::size_t value = N;
};
Run Code Online (Sandbox Code Playgroud)
实际上,类型参数也可以使用相同的原理.现在你可以传递任何bitset,比如steal_it< std::bitset<16> >::value(注意使用size_t,而不是int!).因为我们还没有可变参数的许多模板参数,所以我们必须将自己限制为特定的参数计数,并重复steal_it模板特化以计数从1到N.另一个难点是扫描具有混合参数的类型(类型和非类型参数).这可能是非常重要的解决方案.
如果你没有类型,但只有它的一个对象,你可以使用一个技巧,在编译时仍然得到一个值:
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
}
Run Code Online (Sandbox Code Playgroud)
诀窍是使函数模板自动推导出类型,然后返回对字符数组的引用.该函数不需要定义,唯一需要的是它的类型.
小智 8
我喜欢 Marc Garcia 的答案,因为它展示了如何以通用方式提取模板参数,但我相信他的示例可以更简单:
#include <type_traits>
#include <iostream>
template<int>
struct MyType {};
template<template <int> typename T, int N>
constexpr int extract(const T<N>&) { return N; }
int main() {
constexpr MyType<5> myObj;
std::cout << extract(myObj);
}
Run Code Online (Sandbox Code Playgroud)
您可以使用参数推导和未评估的上下文在C++ 11中轻松完成此操作(请注意,为方便起见,演示使用C++ 14的可变模板功能).
#include <type_traits>
#include <iostream>
template<int>
struct foo {};
template<int arg_N>
struct val {
static constexpr auto N = arg_N;
};
template<template <int> typename T, int N>
constexpr auto extract(const T<N>&) -> val<N>;
template<typename T>
constexpr auto extract_N = decltype(extract(std::declval<T>()))::N;
int main() {
std::cout << extract_N<foo<5>>;
}
Run Code Online (Sandbox Code Playgroud)