I want a way of preserving if the type is a pointer, const, etc upon a cast. See the following.
template<typename type>
void test(type t) {
std::cout << "t const? = " << std::is_const<decltype(t)>() << std::endl;
int x = (int) t;
std::cout << "x const? = " << std::is_const<decltype(x)>() << std::endl;
};
int main() {
const int x = 0;
int y = 0;
test<const int>(x);
test<int>(y);
}
>>> t const? = 1
>>> x const? = 0
>>> t const? = 0
>>> x const? = 0
How do I make it so that the function prints the following? In other words, how do I make it so that if the template argument is const, x is also const?
>>> t const? = 1
>>> x const? = 1
>>> t const? = 0
>>> x const? = 0
I would like to avoid having to do anything like the following.
// bad
if constexpr (std::is_const<decltype(t)>()) {
// do const cast
} else {
// do non const cast
}
The specific scenario I have is I have a const or non-const void pointer and want to cast it to a pointer with a type, whilst preserving the constness.
Edit: This is a poor example. You can use type x = (type) t
. I wanted a solution using type traits because this isn't a valid solution for me.
CodePudding user response:
Your example isnt the best to illustrate the actual issue to cast a void*
, possibly const
, to some T*
with same constness, because you can simply replace the line with type x = t;
to get desired output.
However, you can use a type trait:
#include <iostream>
#include <type_traits>
template <typename From,typename To>
struct preserve_const {
using type = std::remove_const<To>::type;
};
template <typename From,typename To>
struct preserve_const<const From,To> {
using type = const To;
};
template<typename type>
void test(type t) {
std::cout << "t const? = " << std::is_const<decltype(t)>() << std::endl;
typename preserve_const<type,int>::type x = t;
std::cout << "x const? = " << std::is_const<decltype(x)>() << std::endl;
};
int main() {
const int x = 0;
int y = 0;
test<const int>(x);
test<int>(y);
}
Or as mentioned in comments and perhaps much simpler:
template <typename type,typename T>
using the_type = std::conditional_t< std::is_const_v<type>,const T,T>;