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

呱呱

我有一个简单的基类Shape及其派生类Ball。目的是在标量类型和尺寸上具有通用性,因此可以使用模板。

#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;
}

我想使用部分模板专门化,以便根据尺寸计算体积。代码可以工作,但是如果我必须专门研究另一种类型(例如double),代码将很麻烦(代码将是相同的)。

我知道我无法对虚拟方法进行部分模板专门化,但是当我使用上面的注释代码时,我遇到了以下错误而不是错误:模板可能不是“虚拟”的

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> {

我并没有真正得到这个错误,如何避免它,以及有什么办法优雅地获得这种通用性?

Angew不再为SO感到骄傲

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

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/3is 1,因为它是整数除法。

另外,要使其真正保持类型无关,您应将常量转换为T

return static_cast<T>(M_PI) * radius * radius;
return 4 / static_cast<T>(3.0) * static_cast<T>(M_PI) * radius * radius * radius;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

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

来自分类Dev

C ++部分模板模板专业化

来自分类Dev

C ++部分模板专业化混淆

来自分类Dev

C ++部分模板专业化问题

来自分类Dev

C ++模板部分专业化

来自分类Dev

C ++部分模板专业化混淆

来自分类Dev

模板类方法的部分专业化或实例化

来自分类Dev

C ++-可变参数模板部分专业化

来自分类Dev

模板类成员函数的C ++部分专业化

来自分类Dev

避免C ++(部分)模板专业化中的代码重复

来自分类Dev

C ++部分模板专业化-设计简化

来自分类Dev

具有继承的C ++模板部分专业化

来自分类Dev

C ++无法选择正确的部分模板专业化

来自分类Dev

具有STL容器的部分C ++模板专业化

来自分类Dev

C ++部分模板专业化和Natvis

来自分类Dev

C ++模板专业化/部分和全部

来自分类Dev

C ++模板专业化

来自分类Dev

C ++显式专业化不能访问primay模板成员,但是可以访问部分专业化成员?

来自分类Dev

类模板方法专业化

来自分类Dev

模板和方法专业化

来自分类Dev

如何防止C ++模板的专业化?

来自分类Dev

基础类的C ++模板专业化

来自分类Dev

C ++模板专业化/重载

来自分类Dev

模板功能专业化C ++

来自分类Dev

子类型的C ++模板专业化

来自分类Dev

C ++模板专业化冗余减少

来自分类Dev

C ++模板专业化和继承

来自分类Dev

C ++模板专业化和Xcode

来自分类Dev

C ++类模板专业化