Как выяснить, если объект является вектором

Я перевожу код Java на C ++, но у меня возникли проблемы с этой функцией.

private static boolean isArray(Object aObject){
return aObject.getClass().isArray();
}

По сути, мне нужно знать, является ли объект вектором любого типа и любого шаблона. (Я использую векторы вместо массивов в моем коде C ++.)

например, на выходе должно быть что-то вроде этого.

//define some variables
int a=3;
double arr[]={1.0,2.0,3.0,4.0};
vector<int> vecint ({1,2,3});
vector<double> vecdouble ({1.0,2.0});
Class B {};//function output:
bool b;

b=function(a); //returns false
b=function(arr); // returns false
b=function(vecint); //returns true
b=function(vecdouble); //returns true
b=function(B); //returns false

0

Решение

В C ++ не каждая вещь является объектом. Функция может занять что-нибудь, и не все в C ++ является объектом. Таким образом, будет сложно сделать вывод во время выполнения, если какая-то случайная вещь, передаваемая в функцию, является vector или что-то совершенно не связанное. Кроме того, будет невозможно объявить функцию, которая может принимать что-нибудь, не прибегая к void* (пожалуйста, не надо), templateили какой-то variant объект.

Однако мы можем воспользоваться небольшим метапрограммированием шаблона, чтобы вывести его во время компиляции:

#include <cstdlib>
#include <vector>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

template <typename Type>
class IsArray;

template<typename Element> class IsArray <vector <Element>>
{
public:
enum { mValue = true };
};

template<typename Item> class IsArray
{
public:
enum { mValue = false };
};

int main()
{
int n = 42;
cout << "An int is a vector: " << boolalpha << IsArray<int>::mValue << endl;
vector <int> v;
cout << "A vector <int> is a vector: " << boolalpha << IsArray<vector<int>>::mValue << endl;

}

Выход:

An int is a vector: 0
A vector <int> is a vector: 1

Живая демо


На самом деле, это может быть упрощено в дальнейшем появиться как будто мы делаем вывод во время выполнения, хотя он все еще выполняется во время компиляции:

#include <iostream>
#include <vector>
using namespace std;

template <typename Element> bool IsArray (const vector <Element>& vec)
{
return true;
}

template <typename Item> bool IsArray (const Item& item)
{
return false;
}

int main()
{
int n = 42;
cout << "An int is a vector: " << boolalpha << IsArray (n) << endl;
vector <int> v;
cout << "A vector <int> is a vector: " << boolalpha << IsArray (v) << endl;
}

Выход такой же.

Live Demo

2

Другие решения

Это использует в своих интересах дизайн Java (главным образом, что все происходит из Object). C ++ не имеет такого требования. Когда вы объявляете std::vectorэто вектор. Если нет, то это не так. Если у вас нет ужасного объявления функции, которое принимает void*вам нужно будет указать тип параметра, который принимает функция (явно или через шаблон).

2

Вам нужно использовать черту типа. Я имею в виду, что компилятор знает тип при компиляции вашего кода и применяет его к соответствующим образом перегруженной функции (или конструктору в данном случае), и вы можете использовать это в своих интересах. Давайте сделаем черту типа для вектора.

//A type trait for a vector
template <typename T> struct Is_Vector                  { static const bool value = false; };
template <>           struct Is_Vector<std::vector<T>>  { static const bool value = true;  };

Вы даете тип Is_Vector векторный тип, и он будет иметь свой член данных value установить в true; в противном случае его член данных value будет установлен в ложь.

Теперь давайте сделаем функцию, которая использует эту черту типа

// A function that identifies whether the argument is a vector or not
template <typename Type>
bool isVector(Type object){
return Is_Vector<Type>::value;
}

Тестирование это:

int main(){
std::vector<int> vector;
int integer;

std::cout << std::boolalpha;
std::cout <<  isVector(vector) << '\n';
std::cout <<  isVector(integer) << '\n';
}

Создает true для первой функции и false для второй. Лучше всего, что тип выясняется во время компиляции.

Live Demo


Кроме того, вы можете сделать это с помощью двух шаблонных функций, одна из которых является специализированной.

//the compiler will choose this one if you pass in a vector
template <typename T>
bool isVector(std::vector<T> vector_object){
return true;
}

//the compiler will choose this one if you pass in something other than a vector
template <typename T>
bool isVector(T everything_else){
return false;
}

Live Demo

1