#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> {
几乎总是,如果您需要函数模板的部分专门化,您可以使用“委托到类”技巧:
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/3
是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;
我有几个模板参数的模板结构 此结构适用于所有模板,但结果无效的情况除外。我知道,不能实现为void类型,所以我当前的解决方案是使用如下的部分专门化: 这允许执行以下操作: 有没有一种方法可以使编译而不会在C 14标准中进行部分类特化?我可以使用和类型trait组合,但我想找到是否有一种方法: > 模板类方法的特殊化部分显式 模板类方法的实例化
请向我解释选择模板专用化的规则。我举一个例子: 为什么输出为?一般来说,专用类中的默认模板参数会发生什么情况?它会带来一些影响吗?
考虑以下头文件和源文件: 我在
我知道在C++中没有什么比虚拟模板方法更好的了,但似乎它正是我所需要的。有什么办法可以让我使用吗?我很感谢任何建议。 我想通过add方法将实体添加到向量中,这些实体需要是虚拟的,也需要模板,如何避免这种情况?
还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案
这个问题可能太难在标题中的on句子中描述,但这里有一个最小的例子: 当两种类型相同时 当这两种类型是同一类型的类模板的实例化时 天真地说,我们希望第二个部分专门化不会与第一个不明确,因为它感觉“更专门化”,对基础模板上和的推导类型施加更多限制。然而,主要的编译器似乎同意我们的期望是错误的:为什么它不被认为是更专业化的?