请考虑以下声明:
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(...);
答案 0 :(得分:1)
模板参数可以是类型,非类型和模板。
我想你正在看这样的东西
#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;
}
Matrix是一个简单的类模板,可以通过std::initializer_list
进行初始化。矩阵可以与std::vector
或std::list
配合使用以保存其值。
答案 1 :(得分:1)
您编码
template <class T>
bool DoSomething(const T& value);
已经接受std::vector
。如果要在DoSomething方法中执行某些操作,如果T
是向量,则该操作会有所不同,则you can use this approach会检查T
是否是特定类型。不要忘记 模板 是代码生成器。
答案 2 :(得分:1)
好吧,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<std::string>
都具有模板中使用的所有方法。实际上,这段代码几乎可以与所有STL容器一起使用。
答案 3 :(得分:1)
简短答案:通常您做不到。
诚实的答案:是的,可以做到,取决于您打算对参数进行什么处理。在抽象情况下,您将需要泛化函数原型,但是使用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;
}