【发布时间】:2015-09-21 09:47:29
【问题描述】:
我希望能够检查元程序中使用的类的不变量。我的第一个天真的方法是
template <int N>
struct digit
{
static_assert((N >= 0) && (N < 10), "bad invariant");
};
using boom = digit<99>;
然而,这编译没有任何问题。只有在构造非法类时才会触发静态断言。
添加额外的模板参数时可以:
#include <type_traits>
template <int N,
typename = typename std::enable_if<(N >= 0) && (N < 10)>::type>
struct digit;
using crash = digit<-7>;
当我想将此技术应用于用作类型列表的类时:
#include <type_traits>
template <typename ...> struct are_integral;
template <typename T, typename ...Ts>
struct are_integral<T, Ts...>
{
static const bool value = std::is_integral<T>::value &&
are_integral<Ts...>::value;
};
template <>
struct are_integral<> : std::true_type { };
template <typename ...Ts,
typename = typename std::enable_if<are_integral<Ts...>::value>::type>
struct list;
using ok = list<int, long, char>;
using bad = list<double>;
它根本不起作用,因为 gcc 抱怨说
错误:参数包“Ts”必须在模板的末尾 参数列表结构列表;
即使它可以工作,该类也是无用的,因为模板参数包不反映类型列表。
所以我尝试使用“非法”基类:
template <typename> struct check;
template <typename ...Ts>
struct list : check<typename std::enable_if<are_integral<Ts...>::value>::type>
{ };
using ok = list<int, long, char>;
using bad = list<double>;
这编译没有问题。
有没有办法在 c++11 中完成类似的事情,还是我必须等待概念?
【问题讨论】:
-
如果你不介意间接,你可以使用别名模板而不是直接引用
list模板。不过,我不认为这是一个很好的解决方案。 -
我刚才问的相关问题:stackoverflow.com/questions/11251569/…。如您所见,问题与模板实例化有关,编译器会尽可能长时间地延迟模板实例化。目前,我想不出一种在不显式访问类成员的情况下触发实例化的方法,但我会继续思考!
标签: c++ c++11 template-meta-programming