C++ template: add const to type if template arg is const

  • A+
Category:Languages

I have a class:

struct Foo {   vector<float> data; }; 

and I have a templated function that takes a 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 ... } 

How can I make ptr be const float * iff T is const? I know about add_const and is_const but don't see how to use them here. (My real struct is more complicated and I don't have direct access to its internals; it's actually an OpenCV cv::Mat.) I can use recent (C++14/C++17) features if needed.

I'll use it like this:

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

 


Most likely, you actually just want the type of the expression &arg.data[0], for which you can use decltype.

You can also use std::conditional to distinguish the cases.

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

If instead of float *, you had a second type parameter U, you would include 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 ... } 

I have marked where C++14 and C++17 has nicer syntax for equivalent use. C++11 lack of template usings and template variables results in verbose type functions :(.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: