是否可以有一个模板函数,可以将向量和非向量类型都作为参数
Is it possible to have a template function that can take both vector and non-vector type as a parameter?
考虑以下声明:
template <class T>
bool DoSomething(const T& value);
template <class D>
bool DoSomething(const std::vector<D>& value);
有可能以某种方式将其合并为单个函数声明吗?例如:
template <class T, class D> bool DoSomething(...);
您对进行编码
template <class T>
bool DoSomething(const T& value);
已经在接受CCD_ 1。如果你想在DoSomething方法中做一些不同的事情,如果T
是一个向量,那么你可以使用这种方法来检查T
是否是一个特定的类型。不要忘记模板是代码生成器
模板参数可以是类型、非类型和模板。
我想你看到的是类似的东西
#include <iostream>
#include <list>
#include <vector>
#include <string>
template <typename T, template <typename, typename> class Cont >
class Matrix{
public:
explicit Matrix(std::initializer_list<T> inList): data(inList){
for (auto d: data) std::cout << d << " ";
}
int getSize() const{
return data.size();
}
private:
Cont<T, std::allocator<T>> data;
};
int main(){
std::cout << std::endl;
Matrix<int, std::vector> myIntVec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << std::endl;
std::cout << "myIntVec.getSize(): " << myIntVec.getSize() << std::endl;
Matrix<std::string, std::list> myStringList{"one", "two", "three", "four"};
std::cout << std::endl;
std::cout << "myStringList.getSize(): " << myStringList.getSize() << std::endl;
std::cout << std::endl;
}
矩阵是一个简单的类模板,可以通过std::initializer_list
进行初始化。矩阵可以与std::vector
或std::list
一起使用以保持其值。
实时演示
好吧,template <class T> bool DoSomething(const T& value);
也可以用任何向量调用。模板只是代码生成器。因此,无论T
类是什么,只要它具有所有必需的成员,就可以用作模板参数。
例如,以下方法可行:
#include <iostream>
#include <vector>
#include <string>
class MyContainer {
public:
size_t size() const
{
return 2;
}
int front() const
{
return 0;
}
int back() const
{
return 1;
}
};
template<class T>
void foo(const T& t)
{
if (t.size() >= 2)
{
std::cout << "(" << t.front() << ", " << t.back() << ")" << std::endl;
}
}
int main()
{
std::vector<std::string> stringVec{ "abc", "def" };
MyContainer cont;
foo(stringVec); // prints "(abc, def)"
foo(cont); // prints "(0, 1)"
}
这是因为MyContainer
和std::vector
0都具有模板中使用的所有方法。实际上,这段代码应该适用于几乎所有的STL容器。
简短回答:从基因上来说,你不能。
诚实的回答:是的,这是可以做到的,取决于你打算如何处理争论。在抽象的情况下,您需要泛化函数原型,但仍然使用SFINAE对模板进行了两次专门化,它进行了三次声明,而不是两次声明。
长答案:在某些情况下,您可以利用if constexpr
#include <iostream>
#include <type_traits>
#include <vector>
template<typename Test, template<typename...> class Ref>
struct is_specialization : std::false_type {};
template<template<typename...> class Ref, typename... Args>
struct is_specialization<Ref<Args...>, Ref>: std::true_type {};
template <class T> bool DoSomething(const T& arg)
{
if constexpr(is_specialization<T, std::vector>::value)
{
return !arg.empty();
} else
{
return bool(arg);
}
}
int main()
{
std::vector<int> s;
std::cout << DoSomething(s) << std::endl;
std::cout << DoSomething(1) << std::endl;
}
相关文章:
- C++中函数的向量返回类型引发错误
- 具有 STL 向量类型成员的类的复制内存
- 创建一个类来访问和指定向量类型,并构建一个获取位置并为其分配区域的类
- 是否可以有一个模板函数,可以将向量和非向量类型都作为参数
- 具有基元类型的模板向量类型
- 在索引和值类型上参数化的惯用向量类型
- 使用迭代器成员函数是否仅适用于某些向量类型"empty()"?
- 通过glUniform 将 GLM 的向量类型传递给 OpenGL
- 尝试将用户定义的向量类型插入用户定义的类型向量
- 使用类作为向量类型时出错 - "Undeclared identifier"
- 在C++中,当两个向量类型不同时,如何将值存储到向量内部的向量中
- 如何访问和存储向量类型的结构成员
- 按参数中的向量类型重载函数
- boost::variant:具有递归向量类型的奇怪行为
- LLVM 传递计数向量类型指令
- 用异构boost::融合向量类型数据填充std::vector
- 如何定义自定义类的向量类型
- 真正的动态向量类型
- 如何在类的属性/变量中使用组合类作为向量类型
- 更快地删除向量类型