Lorah Attkins
Lorah Attkins

Reputation: 5856

Trait for non qualified or pointer/reference types

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.

Update

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

Answers (2)

NathanOliver
NathanOliver

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

Aykhan Hagverdili
Aykhan Hagverdili

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

Related Questions