检查模板是否具有特定类型的专业化(Check if a template has a specialization for a given type)

编程入门 行业动态 更新时间:2024-10-12 16:30:13
检查模板是否具有特定类型的专业化(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 {};

Suppose we have a metafunction like this:

template<typename LHS , typename RHS> struct add;

And we have a set of specializations for known types. For example, integral wrappers:

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

A few days ago, we create a new class, and we specialize addition for this class:

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>> {};

As you can see, I used add metafuntion to perform the addition of the coordinates. So any type that has a specialization for add metafunction can be used as point_2d coordinates.

My question is: Is there any way to check if a template has a specialization with a given type as argument?

Something like this:

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的想法是通过assert提供用户友好的编译器错误。 如果我可以检查(以下是point_2d示例),如果传递的坐标是可添加的(也就是说,add metafuncion的专门化是为该坐标定义的或未定义的),则可以提供更多可读的错误,如“该坐标不可添加。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 ^

@BartekBanachewicz the idea is to provide user friendly compiler errors through asserts. If i can check (Following with the point_2d example) if the coordinates passed are addable (That is, a specialization of add metafuncion is or not defined for that coordinates), I can provide more readable errors like "That coordinates are not addable. point_2d needs addable coordinates for point addition", instead of the common horrible template instantation errors.

Given that this is the motivation of your question would not this be an easier and more direct solution:

#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 diagnoses:

main.cpp:26:19: required from here main.cpp:12:2: error: static assertion failed: Types are not addable. Need specialization

Clang 3.3 diagnoses:

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 ^

更多推荐

本文发布于:2023-07-27 07:35:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1287144.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模板   类型   Check   type   specialization

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!