是否可以有一个模板函数,可以将向量和非向量类型都作为参数

Is it possible to have a template function that can take both vector and non-vector type as a parameter?

本文关键字:向量 类型 参数 有一个 函数 是否      更新时间:2023-10-16

考虑以下声明:

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::vectorstd::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)"
}

这是因为MyContainerstd::vector0都具有模板中使用的所有方法。实际上,这段代码应该适用于几乎所有的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;
}