当前位置: 首页 > 知识库问答 >
问题:

虚方法的C++部分模板专门化

赵佐
2023-03-14
#include <iostream>
#include <array>
#include <cmath>

template<typename T, std::size_t DIM>
class Shape {
public:
    Shape(std::array<T,DIM> base_point) : base_point_(base_point) {}
    virtual T volume() const = 0;
protected:
    std::array<T,DIM> base_point_;
};

template<typename T, std::size_t DIM>
class Ball : public Shape<T,DIM> {
public:
    Ball(std::array<T,DIM> base_point, T radius) : Shape<T,DIM>(base_point), radius_(radius) {}
    virtual T volume() const;
private:
    T radius_;
};

// Cannot use the generic code below because of Template may not be 'virtual' ?
// template<typename T>
// T Ball<T,2>::volume() const { return M_PI * radius_ * radius_; }

template<>
float Ball<float,2>::volume() const { return M_PI * radius_ * radius_; }

// template<typename T>
// T Ball<T,3>::volume() const { return 4/3 * M_PI * radius_ * radius_ * radius_; }

template<>
float Ball<float,3>::volume() const { return 4/3 * M_PI * radius_ * radius_ * radius_; }

int main() {
    Ball<float,2> circle{{0.2f,0.3f}, 4.0f};
    std::cout << circle.volume() << std::endl;
}
shape_generic_naive.cpp:24:25: error: invalid use of incomplete type ‘class Sphere<T, 2ul>’
 T Sphere<T,2>::volume() const {return M_PI * radius_ * radius_; }
                         ^
shape_generic_naive.cpp:15:7: error: declaration of ‘class Sphere<T, 2ul>’
 class Sphere : public Shape<T,DIM> {

共有1个答案

汪飞捷
2023-03-14

几乎总是,如果您需要函数模板的部分专门化,您可以使用“委托到类”技巧:

template <class T, std::size_t DIM>
struct BallVolume;

template <class T>
struct BallVolume<T, 2>
{
  static T compute(T radius) { return M_PI * radius * radius; }
};

template <class T>
struct BallVolume<T, 3>
{
  static T compute(T radius) { return 4.0/3.0 * M_PI * radius * radius * radius; }
};


template<typename T, std::size_t DIM>
class Ball : public Shape<T,DIM> {
public:
    Ball(std::array<T,DIM> base_point, T radius) : Shape<T,DIM>(base_point), radius_(radius) {}
    virtual T volume() const { return BallVolume<T, DIM>::compute(radius_); }
private:
    T radius_;
};

请注意,3D卷的公式不正确:4/31,因为它是整数除法。

此外,为了使它真正与类型无关,您应该将常数强制转换为t:

return static_cast<T>(M_PI) * radius * radius;
return 4 / static_cast<T>(3.0) * static_cast<T>(M_PI) * radius * radius * radius;
 类似资料:
  • 我有几个模板参数的模板结构 此结构适用于所有模板,但结果无效的情况除外。我知道,不能实现为void类型,所以我当前的解决方案是使用如下的部分专门化: 这允许执行以下操作: 有没有一种方法可以使编译而不会在C 14标准中进行部分类特化?我可以使用和类型trait组合,但我想找到是否有一种方法: > 模板类方法的特殊化部分显式 模板类方法的实例化

  • 请向我解释选择模板专用化的规则。我举一个例子: 为什么输出为?一般来说,专用类中的默认模板参数会发生什么情况?它会带来一些影响吗?

  • 考虑以下头文件和源文件: 我在

  • 我知道在C++中没有什么比虚拟模板方法更好的了,但似乎它正是我所需要的。有什么办法可以让我使用吗?我很感谢任何建议。 我想通过add方法将实体添加到向量中,这些实体需要是虚拟的,也需要模板,如何避免这种情况?

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 这个问题可能太难在标题中的on句子中描述,但这里有一个最小的例子: 当两种类型相同时 当这两种类型是同一类型的类模板的实例化时 天真地说,我们希望第二个部分专门化不会与第一个不明确,因为它感觉“更专门化”,对基础模板上和的推导类型施加更多限制。然而,主要的编译器似乎同意我们的期望是错误的:为什么它不被认为是更专业化的?