我如何static_assert
这样?也许Boost支持它,如果不是C++或C++ 11中的新特性?做一个static_assert,模板类型是另一个模板
template<T>
struct foo {};
template<FooType>
struct bar {
static_assert(FooType is indeed foo<T> for some T,"failure"); //how?
};
我如何static_assert
这样?也许Boost支持它,如果不是C++或C++ 11中的新特性?做一个static_assert,模板类型是另一个模板
template<T>
struct foo {};
template<FooType>
struct bar {
static_assert(FooType is indeed foo<T> for some T,"failure"); //how?
};
你可以沿着这些线做些事情。给定一个特点是可以验证类是否是一个类模板的一个实例:
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<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 { };
在你的程序如下使用它一类是模板的任意数量的(类型)参数的情况下,像这样:
#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!
}
这是live example。
你(或这里的其他人)是否认为通过Vandevoorde和Josuttis读的书“C++模板:完全指南”的知识可以让我做这是我自己的? –
嗯,可能不会,因为'std :: true_type'是一个C++ 11功能:(似乎没有任何新的模板书籍围绕C++ 11 –
@ roger.james:这是一个很好的但是,正如你所提到的,在这个答案中,我使用了C++ 11中没有提供的特性(尤其是可变参数模板)。 –
至于别人写的,
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目前无法处理这个限制。
This不是答案。复制/粘贴他人的答案,然后评论它并不是一个合适的答案。如果您对某人的回答有评论,请对他们的回答留言。 – xaxxon
谁是“别人”?请更新此答案,以便向您复制此代码的人提供正确的[归属地](https://stackoverflow.blog/2009/06/25/attribution-required/)。是[Xeo的答案在这里](https://stackoverflow.com/a/12919396)还是其他答案? –
欢迎来到2017年,你们两个! :)如果你喜欢,可以自由地将“别人”编辑为“Andy Prowl”。 – Quuxplusone
一些小的改进,在其他的答案:
const
,volatile
,而引用类型通过的std ::衰变constexpr
变量我有意不把std :: decay_t放在is_template_for_v上,因为类型特征应该同样地工作,不管它是否用_v后缀调用。
这确实需要C++ 17的std::conjunction
,但您可以删除可变参数或使用C++ 11/14实现自己的conjunction
。
template<template<class...> class tmpl, typename T>
struct _is_template_for : public std::false_type {};
template<template<class...> class tmpl, class... Args>
struct _is_template_for<tmpl, tmpl<Args...>> : public std::true_type {};
template<template<class...> class tmpl, typename... Ts>
using is_template_for = std::conjunction<_is_template_for<tmpl, std::decay_t<Ts>>...>;
template<template<class...> class tmpl, typename... Ts>
constexpr bool is_template_for_v = is_template_for<tmpl, Ts...>::value;
用法:
static_assert(is_template_for_v<std::vector, std::vector<int>>); // doesn't fire
一个相关的问题都可以找到[这里](HTTP://计算器。com/questions/12919310/c-detect-templated-class/12919396) –