Добавьте const к типу, если шаблон arg является const - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть класс:

struct Foo {
  vector<float> data;
};

, и у меня есть шаблонная функция, которая принимает Foo &:

template<typename T>
void f(T& arg) {
  using ftype = float *;    // <-- would like this to be const float * if T is const
  ftype ptr = &arg.data[0];
  // ... do stuff with ptr ...
}

Как мне сделать ptr равным const float *, если T является постоянным?Я знаю о add_const и is_const, но не вижу, как их использовать здесь.(Моя настоящая структура более сложная, и у меня нет прямого доступа к ее внутренним компонентам; на самом деле это OpenCV cv::Mat.) Я могу использовать последние (C ++ 14 / C ++ 17) функции, если это необходимо.

Я буду использовать это так:

Foo foo1 = Foo();
f(foo1); // modifiable in f
const Foo cfoo = Foo();
f(cfoo); // const, should not be modifiable in f

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018
template<class Src, class Dst>
using transcribe_const_t = std::conditional_t<std::is_const<Src>{}, Dst const, Dst>;
template<class Src, class Dst>
using transcribe_volatile_t = std::conditional_t<std::is_volatile<Src>{}, Dst volatile, Dst>;
template<class Src, class Dst>
using transcribe_cv_t = transcribe_const_t< Src, transcribe_volatile_t< Src, Dst> >;

сейчас

template<typename T>
void f(T& arg) {
  using ftype = transcribe_cv_t<T, float>*;
  ftype ptr = &arg.data[0];
  // ... do stuff with ptr ...
}

делает то, что вы просите (и немного больше).

0 голосов
/ 28 сентября 2018

Скорее всего, вам просто нужен тип выражения &arg.data[0], для которого вы можете использовать decltype.

Вы также можете использовать std::conditional для различенияпадежи.

template<typename T>
void f(T& arg) {
  // C++17: using ftype = std::conditional_t<std::is_const_v<T>, const float *, float *>;
  using ftype = typename std::conditional<std::is_const<T>::value, const float *, float *>::type;

  ftype ptr = &arg.data[0];
  // ... do stuff with ptr ...
}

Если бы вместо float * у вас был параметр второго типа U, вы бы включили std::add_const

template<typename T, typename U = float *>
void f(T& arg) {
  // C++17: using ftype = std::conditional_t<std::is_const_v<T>, std::add_const_t<U>, U>;
  using ftype = typename std::conditional<std::is_const<T>::value, typename std::add_const<U>::type, U>::type;
  // ... do stuff with ftype ...
}

Я отметил, где C ++14 и C ++ 17 имеют более приятный синтаксис для эквивалентного использования.C ++ 11 отсутствие шаблона using s и переменных шаблона приводит к подробным функциям типа: (.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...