Я перевожу код 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
В 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;
}
Выход такой же.
Это использует в своих интересах дизайн Java (главным образом, что все происходит из Object
). C ++ не имеет такого требования. Когда вы объявляете std::vector
это вектор. Если нет, то это не так. Если у вас нет ужасного объявления функции, которое принимает void*
вам нужно будет указать тип параметра, который принимает функция (явно или через шаблон).
Вам нужно использовать черту типа. Я имею в виду, что компилятор знает тип при компиляции вашего кода и применяет его к соответствующим образом перегруженной функции (или конструктору в данном случае), и вы можете использовать это в своих интересах. Давайте сделаем черту типа для вектора.
//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 для второй. Лучше всего, что тип выясняется во время компиляции.
Кроме того, вы можете сделать это с помощью двух шаблонных функций, одна из которых является специализированной.
//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;
}