gpt4 book ai didi

c++ - 函数模板特化语法聚合模板化类型

转载 作者:行者123 更新时间:2023-11-30 01:38:13 25 4
gpt4 key购买 nike

关于函数模板特化,我需要一些语法方面的帮助。以下是一个简化的场景:

基本标题:

template <typename T>
void Foo(T* t) { TRACE("Default Foo impl"); } // <-- default implementation

template <typename T>
struct Base
{
explicit Base()
{
static_assert(std::is_base_of<Base, T>::value, "T must derive from Base");
Foo(static_cast<T*>(this));
}
};

Derived_X header :

struct Derived_X : public Base<Derived_X>
{
explicit Derived_X() : Base<Derived_X> { } { }
};

// no specialization will be implemented --> using default

Derived_Y 标题:

struct Derived_Y : public Base<Derived_Y>
{
explicit Derived_Y() : Base<Derived_Y> { } { }
};

template <> // Foo specialization for Derived_Y
void Foo<Derived_Y>(Derived_Y* t)
{
Foo(static_cast<Base<Derived_Y>*>(t)); // <-- call default impl
TRACE("Derived_Y Foo impl");
}

Derived_Z header :

template <typename T>
struct Derived_Z : public Base<T>
{
explicit Derived_Z() : Base<T> { }
{
static_assert(std::is_base_of<Derived_Z, T>::value, "T must derive from Derived_Z");
}
};

/* What does this specialization look like?
template <typename T>
void Foo<Derived_Z<T>>(Derived_Z<T>* t)
{
Foo(static_cast<Base<T>*>(t)); // <-- call default impl
TRACE("Derived_Z<T> Foo impl");
}
// */

MostDerived header :

struct MostDerived : public Derived_Z<MostDerived>
{
explicit MostDerived() : Derived_Z<MostDerived> { } { }
};

template <>
void Foo<MostDerived>(MostDerived* t)
{
Foo(static_cast<Derived_Z<MostDerived>*>(t)); // <-- call Derived_Z impl
TRACE("MostDerived Foo impl");
}

用法:

int main()
{
Derived_X dx { }; // <-- "Default Foo impl"
Derived_Y dy { }; // <-- "Default Foo impl" && "Derived_Y Foo impl"
MostDerived md { }; // <-- "Default Foo impl" && "MostDerived Foo impl"
}

我无法确定如何为 Derived_Z 专门化 Foo。任何帮助将不胜感激!

最佳答案

特化函数模板通常被认为是一种糟糕的形式。您将无法部分特化(正如您所注意到的),并且在重载解决方案中不会考虑它们。相反,只需创建重载,让重载解析处理其余部分。

// no template at all for Derived_Y
void Foo(Derived_Y* t)
{
Foo(static_cast<Base<Derived_Y>*>(t)); // <-- call default impl
TRACE("Derived_Y Foo impl");
}

// a regular template (no specialization) for Derived_Z<T>
template <typename T>
void Foo(Derived_Z<T>* t)
{
Foo(static_cast<Base<T>*>(t)); // <-- call default impl
TRACE("Derived_Z<T> Foo impl");
}

// again, no template for MostDerived
void Foo(MostDerived* t)
{
Foo(static_cast<Derived_Z<MostDerived>*>(t)); // <-- call Derived_Z impl
TRACE("MostDerived Foo impl");
}

现在,您可能要考虑更改基本实现以仅接受 Base<T>*而不是 T* .假设你有 Derived_Y2源自 Derived_Y , 但您尚未为 Foo(Derived_Y2*) 定义重载.打电话Foo()使用指向 Derived_Y2 的指针然后将转到Foo(T*)T被推断为 Derived_Y2 ,因为这是比 Foo(Derived_Y*) 更好的匹配

struct Derived_Y2 : Derived_T { };
Derived_Y2 y2; // "Default Foo impl"

通过将基本实现更改为:

template<class T>
void Foo(Base<T>*) { TRACE("Default Foo impl"); }

Foo(Derived_Y*)当给出一个指向 Derived_Y2 的指针时,现在将是一个更好的匹配,因为正如他们所说,它更专业

关于c++ - 函数模板特化语法聚合模板化类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48410678/

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