允许模板中的标量和向量类型
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;
}
};
我正在为信号处理库开发一个 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;
}
};