提问者:小点点

执行static_assert以确定模板类型是另一个模板


我如何像这样static_assert?也许Boost支持它,如果不是C++或C++11中的新特性?

template<T>
struct foo {};

template<FooType>
struct bar {
  static_assert(FooType is indeed foo<T> for some T,"failure"); //how?
};

共2个答案

匿名用户

你可以在这方面做点什么。给定一个可以验证类是否是类模板的实例化的特征:

#include <type_traits>

template<typename T, template<typename> class TT>
struct is_instantiation_of : std::false_type { };

template<typename T, template<typename> class TT>
struct is_instantiation_of<TT<T>, TT> : std::true_type { };

在您的程序中按照以下方式使用它:

template<typename T>
struct foo {};

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of<FooType, foo>::value, "failure");
};

int main()
{
    bar<int> b; // ERROR!
    bar<foo<int>> b; // OK!
}

如果需要,可以对其进行泛化,以检测类是否是具有任意数量(类型)参数的模板的实例,如下所示:

#include <type_traits>

template<template<typename...> class TT, typename T>
struct is_instantiation_of : std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : std::true_type { };

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of<foo, FooType>::value, "failure");
};

然后您可以在程序中这样使用它:

template<typename FooType>
struct bar {
  static_assert(is_instantiation_of<foo, FooType>::value, "failure");
};

int main()
{
    bar<int> b; // ERROR!
    bar<foo<int>> b; // OK!
}

这里有一个活生生的例子。

匿名用户

就像别人写的,

template<typename T, template<typename...> class TT>
struct is_specialization_of : std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_specialization_of<TT<Ts...>, TT> : std::true_type { };

但是,要注意,这只适用于模板参数都是TypeNames的模板类!呈上

typedef std::array<int, 42> MyArray;
static_assert(is_specialization_of<MyArray, std::array>::value, "");

它将完全无法编译。

我相信C++11/C++14/C++17目前还没有办法处理这个限制。