选择具有派生类型的基类型的模板特化

Posted

技术标签:

【中文标题】选择具有派生类型的基类型的模板特化【英文标题】:Choosing template specialization of a base type with derived types 【发布时间】:2021-06-20 02:46:45 【问题描述】:

是否可以为派生类型选择基类型的模板特化?如果不是,那么在不必专门针对每个派生类型的情况下,以下可能的解决方案是什么?

注意:这是我们验证器的简化版本。不同类型有不同的验证要求

template <typename T>
class IsValid_Executor

public:
    auto IsValid(const T& InObj) -> bool = delete;
;

class Bar  ;
class Foo : public Bar  ;

template <>
class IsValid_Executor<void*>

public:
    auto IsValid(const void* InObj)
    
        return InObj != nullptr;
    
;

template <>
class IsValid_Executor<Bar*>

public:
    auto IsValid(const Bar* InObj)
    
        return InObj != nullptr;
    
;

template <typename T>
bool IsValid(const T& InObj)

    return IsValid_Executor<T>.IsValid(InObj);


int main()

    Bar* b;

    IsValid(b); // compiles

    Foo* f;

    IsValid(f); // error: use of deleted function
    IsValid_Executor<void*>.IsValid(f); // compiles
    IsValid_Executor<decltype(f)>.IsValid(f); // error: use of deleted function - why isn't the void* OR the Bar* overload chosen?
    IsValid_Executor<Bar*>.IsValid(f); // compiles - however, I cannot know in the `IsValid<T>` function to choose Bar*

【问题讨论】:

【参考方案1】:

您可以对Bar 的所有派生类使用部分特化。

template <typename T, typename = void>
class IsValid_Executor

public:
    auto IsValid(const T& InObj) -> bool = delete;
;

然后

template <typename D>
class IsValid_Executor<D*, std::enable_if_t<std::is_base_of_v<Bar, D>>>

public:
    auto IsValid(const Bar* InObj)
    
        return InObj != nullptr;
    
;

LIVE

【讨论】:

以上是关于选择具有派生类型的基类型的模板特化的主要内容,如果未能解决你的问题,请参考以下文章

C++模板进阶操作 —— 非类型模板参数模板的特化以及模板的分离编译

C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译

C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译

模板的全特化与偏特化

C++初阶:模板进阶非类型模板参数 | 模板的特化 | 模板分离编译

C++初阶:模板进阶非类型模板参数 | 模板的特化 | 模板分离编译