Here is a type trait which - I feel - could fit in std next to std::add_const and std::remove_const:
#include <type_traits>
template <typename T>
struct set_constness_of {
template <typename U>
struct by {
using type = typename std::conditional<
std::is_const<U>::value,
typename std::add_const<T>::type,
typename std::remove_const<T>::type
>::type;
};
};
Note this is intentionally C++11 to minimize requirements for using it. One can obviously define set_constness_of_t in which by is a type rather than a struct with a type.
I've also written a tiny sample program (coliru.com) to ensure it runs, at least for some cases.
/* the above definition of set_constness_of goes here (paste it) */
#inlcude <iostream>
struct foo {
void m() { std::cout << "Non-const\n"; }
void m() const { std::cout << "Const\n"; }
};
template <class T> void call_m() { T().m(); }
int main() {
call_m<foo>();
using bar = const int;
call_m< set_constness_of<foo>::by<bar>::type >();
}
Questions:
- Is this correctly defined for all cases?
- What do you think about placing the second template parameter as an inner struct's template param, rather than having two template parameters on the outer struct?
- What do you think about the choice of naming?
Other comments are welcome.