c++ - 避免模​​板扩散

标签 c++ templates

我正在开发一个相当紧密耦合的库,到目前为止,它已经明确假设所有计算都是用 double 完成的。我正在将一些核心类转换为模板,以便我们可以开始计算 std::complex<double> .到目前为止,我已经对大约 10 个类(class)进行了模板化,并注意到模板激增的趋势。当一个类被模板化时,任何其他使用模板化类的类似乎也需要模板化。我想我可以通过为我的模板定义抽象基类来避免这种扩散,这样其他类就可以使用指向抽象类的指针,然后引用 double。或 std::complex<double>派生类的版本。这似乎在 header 级别起作用,但是当我深入研究源文件时,模板化类通常会具有计算 double 类型的值或值容器的函数。或 std::complex<double> .仅仅因为源文件中的几行由于其他一些类的返回类型而不同,就对整个类进行模板化似乎是一种浪费。

auto的使用似乎是解决此问题的一种可能方法,但我不能 100% 确定它会起作用。假设我有一个抽象基类 AbstractFunction从中Function<Scalar>派生,其中 Scalar可以是doublestd::complex<double> .现在假设我们有两个成员函数:

virtual Scalar Function<Scalar>::value(double x);
virtual void Function<Scalar>::values(std::vector<Scalar> &values, std::vector<double> x);

并且假设我有一些其他类(我不想模板化)具有调用其中一个的成员函数。

// populate double x and std::vector<double> xs
auto value = functionPtr->value(x);
std::vector<auto> values;
functionPtr->values(values, xs);
// do something with value and values

哪里functionPtr类型为 std::shared_ptr<AbstractFunction> . 我可以看到 auto为第一种情况工作,但我不相信我可以构建 auto 的 vector 被第二个填满。这是否需要使调用类成为模板?有人可以推荐另一种策略来减少模板的扩散吗?

最佳答案

我认为您假设第一个用例会起作用已经是错误的。如果你有一个抽象基类,那么 value是它的成员,你可以通过std::shared_ptr<AbstractFunction>调用它或 value不是它的成员,只有当您知道派生类的类型时才可用。在第一种情况下,AbstractFunction::value方法必须有一个固定的返回类型,它不能依赖于Scalar , 是派生类的模板参数。

也就是说:根据我的经验,这两个概念通常不能很好地混合。您要么想要创建一个具有完整接口(interface)的抽象基类,要么想要一个模板。在后一种情况下,拥有抽象基类通常没有必要/也没有好处。然后,使用您的模板的代码也适用于模板。

可能对您有帮助的是从 Function 中“导出”模板参数,即

template<typename T>
class Function
{
public:
    using value_type = T;
    value_type value() const;
    // ...
};

在代码的其他部分,使用采用任何 T 的模板。表现得像Function如果你不想直接写出(并限制自己)到 Function :

template<typename T>
void something( const std::shared_ptr<T>& functionPtr )
{
   // ignoring where x comes from...
   using V = typename T::value_type;
   V value = functionPtr->value(x);
   std::vector<V> values;
   functionPtr->values(values, xs);
}

请注意,这只是一个选项,我不知道它是否是您用例的最佳选择。

关于c++ - 避免模​​板扩散,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29853609/

相关文章:

矩阵窗口上的 Java 代码优化计算时间更长

java - mmap() vs Java MappedByteBuffer 性能?

c++ - 基类模板实例化取决于派生类构造函数参数类型

c++ - 使用 C++ 模板魔法进行通用和存在量化

templates - Aurelia:嵌套模板替换

c++ - cout 打印字符串变量无法通过构建

c++ - 使用/不使用 Visual Leak Detector 在 C++ 中检测内存泄漏

c++ - QF模式匹配算法伪代码转c代码

C++ 段错误 : Passing a string to a node in a linked list

c++ - C++ 中是否可以使用无状态访问者模式?