簡體   English   中英

檢查模板是否具有給定類型的特化

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM