允许模板中的标量和向量类型

Allow scalar and vector types in a template

我正在为信号处理库开发一个 class 模板,该模板应该保存标量样本或标量样本的向量(这在例如逐帧信号处理中很常见)。

class 本质上是 std::vector 的外观,增加了一些方便的方法和成员。

对于标量类型,一切都很好。但是当我允许向量作为模板参数时,我 运行 遇到了麻烦。这是我的意思的最小示例:

template <class T>
class Signal
{
    public:
        Signal() = default;
        std::vector<T> samples;
           
        friend std::ostream& operator<<(std::ostream& os, const Signal& obj)
        {
            for (const auto& x : obj.samples)
            {
                os << x << ",";
            }
            return os << std::endl;
        }
}

我显然收到有关 std::vector 类型的右侧操作数缺少“<<”运算符的错误。我想要的是为标量和类似向量的模板参数定义不同的运算符(以及上面最小示例中未显示的其他一些方法)。

我做了一些研究并了解了 SFINAE 的概念,但我无法将这些点联系起来。

谁能指出我正确的方向?我觉得这应该是一个相当普遍的问题。还是我做错了?

您可以使用重载而不是 SFINAE:

template <typename T>
std::ostream& print(std::ostream& os, const T& obj)
{
    return os << obj;
}

template <typename T>
std::ostream& print(std::ostream& os, const std::vector<T>& v)
{
    os << "{";
    const char* sep = "";
    for (const auto& e : v) {
        os << sep;
        print(os, e);
        sep = ", ";
    }
    return os << "}";
}

template <class T>
class Signal
{
public:
    Signal() = default;
    std::vector<T> samples;
       
    friend std::ostream& operator<<(std::ostream& os, const Signal& obj)
    {
        for (const auto& x : obj.samples)
        {
            print(os, x) << ",";
        }
        return os << std::endl;
    }
};

Demo