我如何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) –