gpt4 book ai didi

c++ - 检查模板是否具有给定类型的特化

转载 作者:太空狗 更新时间:2023-10-29 20:14:05 25 4
gpt4 key购买 nike

假设我们有这样一个元函数:

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 元函数来执行坐标相加。因此,任何具有 add 元函数特化的类型都可以用作 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 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.

鉴于这是您提出问题的动机,这不是一个更简单直接的解决方案:

#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
^

关于c++ - 检查模板是否具有给定类型的特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17906888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com