【问题标题】: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*
}

【问题讨论】:

    标签: c++ templates


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多