C++ template: add const to type if template arg is const
Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
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
c++ c++11 templates
add a comment |Â
up vote
6
down vote
favorite
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
c++ c++11 templates
4
If you wroteauto ptr = &arg.data[0];
,decltype(ptr)
would beconst float*
, no type traits needed
â Justin
2 hours ago
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
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
c++ c++11 templates
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
c++ c++11 templates
c++ c++11 templates
asked 3 hours ago
GaryO
1,315915
1,315915
4
If you wroteauto ptr = &arg.data[0];
,decltype(ptr)
would beconst float*
, no type traits needed
â Justin
2 hours ago
add a comment |Â
4
If you wroteauto ptr = &arg.data[0];
,decltype(ptr)
would beconst float*
, no type traits needed
â Justin
2 hours ago
4
4
If you wrote
auto ptr = &arg.data[0];
, decltype(ptr)
would be const float*
, no type traits neededâ Justin
2 hours ago
If you wrote
auto ptr = &arg.data[0];
, decltype(ptr)
would be const float*
, no type traits neededâ Justin
2 hours ago
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
7
down vote
accepted
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 using
s and template variables results in verbose type functions :(.
2
The big win is for C++14:_t
versustypename
::value
. C++17 is only::value
vs_v
.
â Jarod42
2 hours ago
add a comment |Â
up vote
2
down vote
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> >;
now
template<typename T>
void f(T& arg)
using ftype = transcribe_cv_t<T, float>*;
ftype ptr = &arg.data[0];
// ... do stuff with ptr ...
does what you ask (and a bit more).
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
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 using
s and template variables results in verbose type functions :(.
2
The big win is for C++14:_t
versustypename
::value
. C++17 is only::value
vs_v
.
â Jarod42
2 hours ago
add a comment |Â
up vote
7
down vote
accepted
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 using
s and template variables results in verbose type functions :(.
2
The big win is for C++14:_t
versustypename
::value
. C++17 is only::value
vs_v
.
â Jarod42
2 hours ago
add a comment |Â
up vote
7
down vote
accepted
up vote
7
down vote
accepted
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 using
s and template variables results in verbose type functions :(.
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 using
s and template variables results in verbose type functions :(.
edited 11 mins ago
answered 2 hours ago
Caleth
12.8k11431
12.8k11431
2
The big win is for C++14:_t
versustypename
::value
. C++17 is only::value
vs_v
.
â Jarod42
2 hours ago
add a comment |Â
2
The big win is for C++14:_t
versustypename
::value
. C++17 is only::value
vs_v
.
â Jarod42
2 hours ago
2
2
The big win is for C++14:
_t
versus typename
::value
. C++17 is only ::value
vs _v
.â Jarod42
2 hours ago
The big win is for C++14:
_t
versus typename
::value
. C++17 is only ::value
vs _v
.â Jarod42
2 hours ago
add a comment |Â
up vote
2
down vote
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> >;
now
template<typename T>
void f(T& arg)
using ftype = transcribe_cv_t<T, float>*;
ftype ptr = &arg.data[0];
// ... do stuff with ptr ...
does what you ask (and a bit more).
add a comment |Â
up vote
2
down vote
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> >;
now
template<typename T>
void f(T& arg)
using ftype = transcribe_cv_t<T, float>*;
ftype ptr = &arg.data[0];
// ... do stuff with ptr ...
does what you ask (and a bit more).
add a comment |Â
up vote
2
down vote
up vote
2
down vote
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> >;
now
template<typename T>
void f(T& arg)
using ftype = transcribe_cv_t<T, float>*;
ftype ptr = &arg.data[0];
// ... do stuff with ptr ...
does what you ask (and a bit more).
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> >;
now
template<typename T>
void f(T& arg)
using ftype = transcribe_cv_t<T, float>*;
ftype ptr = &arg.data[0];
// ... do stuff with ptr ...
does what you ask (and a bit more).
edited 15 mins ago
Jarod42
108k1297172
108k1297172
answered 1 hour ago
Yakk - Adam Nevraumont
171k18175353
171k18175353
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52559336%2fc-template-add-const-to-type-if-template-arg-is-const%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
4
If you wrote
auto ptr = &arg.data[0];
,decltype(ptr)
would beconst float*
, no type traits neededâ Justin
2 hours ago