![](/img/trans.png)
[英]How to check if a template parameter in a function matches a specialization of a given type alias
[英]Check if a template has a specialization for a given type
假設我們有一個這樣的元函數:
template<typename LHS , typename RHS>
struct add;
我們有一組已知類型的專業化。 例如,整體包裝:
template<typename T1 , T1 VALUE1 , typename T2 , T2 VALUE2>
struct add<std::integral_constant<T1,VALUE1>,std::integral_constant<T2,VALUE2> : public std::integral_constant<std::common_type_t<T1,T2>,VALUE1+VALUE2> {}; //Take advantage of C++14 helpers
幾天前,我們創建了一個新類,我們專門為這個類添加了:
template<typename X , typename Y>
struct point_2d
{
using x = X;
using y = Y;
};
template<typename X1 , typename Y1 , typename X2 , typename Y2>
struct add<point_2d<X1,Y1>,ppoint_2d<X2,Y2>> : public point_2d<add<X1,X2>,add<Y1,Y2>> {};
如您所見,我使用add
metafuntion來執行坐標的添加。 因此,任何具有添加元函數專門化的類型都可以用作point_2d
坐標。
我的問題是: 有沒有辦法檢查模板是否具有給定類型作為參數的特化?
像這樣的東西:
template<template<typename...> class TEMPLATE , typename... Ts>
struct has_specialization;
template<template<typename...> class TEMPLATE , typename... Ts>
struct has_specialization<TEMPLATE<Ts...> /* TEMPLATE<Ts...> exists */ , Ts...> : public std::true_type {};
template<template<typename...> class TEMPLATE , typename... Ts>
struct has_specialization<TEMPLATE<Ts...> /* TEMPLATE<Ts...> doesn't exists */ , Ts...> : public std::false_type {};
@BartekBanachewicz的想法是通過斷言提供用戶友好的編譯器錯誤。 如果我可以檢查(跟隨point_2d示例)如果傳遞的坐標是可添加的(也就是說,是否為該坐標定義了添加元函數的特殊化),我可以提供更多可讀錯誤,例如“那個坐標不可添加。”point_2d需要可添加的點添加坐標“,而不是常見的可怕模板即時錯誤。
鑒於這是您的問題的動機,這不是一個更容易和更直接的解決方案:
#include <type_traits>
template<typename LHS , typename RHS>
using cannot_add = std::integral_constant<bool,std::is_same<LHS,LHS>::value>;
template<typename LHS , typename RHS>
struct add
{
/* Assert some expressively named condition that is always false
but is dependent on a template parameter.
*/
static_assert(!cannot_add<LHS,RHS>::value,
"Types are not addable. Need specialization");
};
template<typename T1 , T1 VALUE1 , typename T2 , T2 VALUE2>
struct add<std::integral_constant<T1,VALUE1>,std::integral_constant<T2,VALUE2>>
: public std::integral_constant<
typename std::common_type<T1,T2>::type,
VALUE1+VALUE2
> {};
int main()
{
add<std::integral_constant<int,1>,std::integral_constant<int,2>> x; // Line 25
add<float,float> y; // Line 26
return 0;
}
GCC 4.8.1診斷:
main.cpp:26:19: required from here
main.cpp:12:2: error: static assertion failed: Types are not addable. Need specialization
Clang 3.3診斷:
main.cpp:12:2: error: static_assert failed "Types are not addable. Need specialization"
static_assert(!cannot_add<LHS,RHS>::value,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:26:19: note: in instantiation of template class 'add<float, float>' requested here
add<float,float> y; // Line 26
^
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.