Я не профессиональный программист, и я прошу прощения, если мой вопрос кажется наивным или неправильным.
Я пытаюсь, чтобы функция члена класса принимала std::array
или std::vector
в аргументах. В частности, я передаю два аргумента, которые должны быть либо std::array
, либо оба std::vector
.
ДО того, как пытаться заставить вышеописанное работать, минимальная настройка того, что у меня было, работала только с std::vector
аргументами. минимальная настройка выглядит следующим образом, где v и p - это те, которые я хотел бы передать как векторы или массивы:
// original version
class my_class_A{
// stuf
};
class my_class_B{
// other stuf
};
class I_am_a_class_of_methods{
public:
inline void my_method(const std::vector<my_class_A> &v,
const std::vector<std::array<uint64_t,2> > &p,
const my_class_B &x,
my_class_B &y){
// `v` and `p` are used to modify `x` and store the result in `y`
return;
};
};
Я понимаю, что мог делать то, что я хочу с перегрузкой функций, однако я решил, что хочу достичь желаемого результата с помощью templates
и std::enable_if
, чтобы заставить меня узнать о них немного больше. Ну, я действительно многому научился, я не знал ... но этого недостаточно. Я в основном пытался настроить черту is_both_array_or_vector
, и std::enable_if
проверит, соответствует ли вызов шаблона шаблону. Последнее, что я попробовал, это следующее, которое скомпилировалось, но оно будет работать только для std::vector
:
// current version
class my_class_A{
// stuf
};
class my_class_B{
// other stuf
};
// set up a type trait to check if both are vector or both are array
template <typename T1, typename T2>
struct is_both_array_or_vector{
enum { value = false };
};
template <typename T1, typename T2, typename A1, typename A2 >
struct is_both_array_or_vector<std::vector<T1, A1>, std::vector<T2, A2> > {
enum { value = true };
};
template <typename T1, typename T2, size_t D>
struct is_both_array_or_vector<std::array<T1, D>, std::array<T2, D> > {
enum { value = true };
};
// conditionally compile with enable_if
class I_am_a_class_of_methods{
public:
template<template<typename,typename> U, template<typename,typename> S,
typename Au, typename As>
typename std::enable_if<is_both_array_or_vector<U<my_class_A, Au>, S<std::array<uint64_t,2>,As> >::value >::type
my_method(const U<my_class_A, Au> &v,
const S<std::array<uint64_t,2>, As> &p,
const my_class_B &x,
my_class_B &y){
// `v` and `p` are used to modify `x` and store the result in `y`
return;
};
};
Когда я компилирую с вызовом std::vector
из main, все работает нормально. Это (конечно) не компилируется с вызовом std::array
(компилятор, конечно, жалуется).
Если бы я только мог сделать аргументы шаблона As
и Au
, которые можно было бы интерпретировать как size_t
тогда шаблон найдет совпадение с вызовом std::array
. Однако это невозможно, так как у меня может быть либо typename
, либо size_t
, но не оба, насколько я знаю. Таким образом, мой вопрос: как мне заставить enable_if работать в этих условиях?