繁体   English   中英

如果模板arg是const,则将const添加到type

[英]Add const to type if template arg is const

我有一节课:

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 * iff T是const? 我知道add_constis_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

最有可能的是,您实际上只需要表达式&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和模板变量的模板导致详细类型函数:(。

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 ...
}

做你所要求的(以及更多)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM