你如何在c ++中使用模板调用非成员函数,其中typename仅在return中?

How do you call a non-member function with a template in c++, where the typename is only in the return?

我的目标是让非成员函数为 return 值使用模板。这样我就可以 return 浮点数组、双精度数组等。我收到“无法推断模板参数 'T'”错误。

这是我尝试使用的方法:

template<typename T>
T* make(double magnitude, double frequency, double radians, double seconds,
        int samplesPerSecond) {
    long samples = length(seconds, samplesPerSecond);
    T *wave = new T[samples];
    for (int i = 0; i < samples; i++) {
        wave[i] = magnitude
                * sin(
                        (2.0 * (M_PI) * frequency * i / samplesPerSecond)
                                + radians);
    }
    return wave;
}

我先尝试正常调用方法

double *ds = make(magnitude, frequency, radians, seconds, samplesPerSecond);

我试过在函数名后添加类型名。

double *ds = make<double>(magnitude, frequency, radians, seconds, samplesPerSecond);

我在网上看了好几页,到目前为止它们都涵盖了成员函数,并解释说不能从 return 类型推导出类型,那么你如何告诉编译器类型?

您可以 很多 使用 non-member 函数执行此操作,按照以下示例,该示例将模板类型的两个值加在一起:

#include <iostream>

template<typename T> T add(const T &val1, const T &val2) {
    return val1 + val2;
}

int main() {
    auto eleven = add<int>(4, 7);
    std::cout << "4   + 7   = " << eleven << '\n';
    auto threePointFour = add<double>(1.1, 2.3);
    std::cout << "1.1 + 2.3 =  " << threePointFour << '\n';
}

该代码的输出如预期的那样:

4   + 7   = 11
1.1 + 2.3 =  3.4

可能您的案例无法正常工作,因为模板函数的定义可能不正确 - 因为您没有提供,所以很难确定。因此,您可能想看看它与我自己的 add 函数相比如何,如上所示。


顺便说一句(因为你的标题表明这可能是你正在尝试的),你也可以 without 使用参数列表中的模板化类型(仅return 类型):

#include <iostream>

template<typename T> T addAndHalve(const double &val1, const double &val2) {
    auto x = (val1 + val2) / 2;
    std::cout << "debug " << x << ": ";
    return x;
}

int main() {
    auto eleven = addAndHalve<int>(4, 7);
    std::cout << "(4   + 7  ) / 2 = " << eleven << '\n';
    auto threePointFour = addAndHalve<double>(1.1, 2.3);
    std::cout << "(1.1 + 2.3) / 2 =  " << threePointFour << '\n';
}

您可以看到这仅影响 return 值,对所有参数使用 double

debug 5.5: (4   + 7  ) / 2 = 5
debug 1.7: (1.1 + 2.3) / 2 =  1.7

我注意到 c++ 标准库有像 lround() 这样的函数,其中 l 表示函数 returns 很长,所以我最终也制作了多个方法。

int16_t* makei(double magnitude, double frequency, double radians,
        double seconds, int samplesPerSecond);
float* makef(double magnitude, double frequency, double radians, double seconds,
        int samplesPerSecond);

这违反了我经常听到的“避免不必要的重载”规则,下面的代码确实有效。

double *ds = make<double>(magnitude, frequency, radians, seconds, samplesPerSecond);

我遇到了另一个阻止它工作的未知错误。