Reputation: 5856
I'm implementing a check to see if a type is stripped of any qualifications:
template <class T>
struct is_plain : std::integral_constant<
bool,
std::is_same_v<T, std::decay_t<T>> // *
>;
Is the logic in std::is_same_v<T, std::decay_t<T>>
, i.e. check if a type is stripped of anything that decay
would remove,available as a standard trait?
If not, is my implementation missing something? I just want to make sure (in a static assertion) that one does not pass pointers or references to some class.
As pointed out by @NathanOliver, decay
won't remove pointerness (if that's a word), so decay_t<int*>==int*
. I wasn't aware of that, so an addition to the desciprion would be that I want to remove pointers from the type as well.
Upvotes: 3
Views: 396
Reputation: 180955
This is a bit verbose, but it should cover every case there is. With
template<typename T>
constexpr auto is_plain_v = !(std::is_function_v<T> || std::is_pointer_v<T> ||
std::is_lvalue_reference_v<T> || std::is_rvalue_reference_v<T> ||
std::is_array_v<T> || std::is_member_object_pointer_v<T> ||
std::is_member_function_pointer_v<T> || std::is_const_v<T> ||
std::is_volatile_v<T>);
And using the driver program
struct Test { void foo(int) {} };
int main ()
{
std::cout << std::boolalpha
<< is_plain_v<int> << '\n'
<< is_plain_v<const int> << '\n'
<< is_plain_v<int&> << '\n'
<< is_plain_v<int&&> << '\n'
<< is_plain_v<const int&> << '\n'
<< is_plain_v<int[2][2]> << '\n'
<< is_plain_v<int(int)> << '\n'
<< is_plain_v<int(*)(int)> << '\n'
<< is_plain_v<void (Test::*)(int)> << '\n';
}
It outputs
true
false
false
false
false
false
false
false
false
Upvotes: 2
Reputation: 29985
Yours won't work for arrays. There is a standard trait that's very similar:
std::is_same_v<T, std::remove_cvref_t<T>>
Upvotes: 2