Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

is_same for parameter pack => is_one_of

24 views
Skip to first unread message

robert badea

unread,
Nov 24, 2018, 7:17:54 AM11/24/18
to
Hello!
I was messing around with C++ and wanted to do a type_trait which would return true if a type is one of the given types.
basically, is_same_v<T,T> with variadic.

This would remove the following boiler plate

struct is_something {
static const bool value = false;
};

template <>
struct is_something<int> {
static const bool value = true;
};

template <>
struct is_something<short> {
static const bool value = true;
};

template <>
struct is_something<long> {
static const bool value = true;
};


with

template<class T>
struct is_something {
static const bool value = is_one_of<T, int, short, long>;
};

I've made the following combinations:

1)

template<class Expected, class... Received>
inline constexpr bool is_one_of = (std::is_same_v<Expected, Received> || ...);

2)

template<class Expected>
struct is_one_of_2
{
template <class ...Received>
static constexpr inline bool exec()
{
return (std::is_same_v<Expected, Received> || ...);
}
};



Usage:

template<class T>
constexpr void exec(T data)
{
if constexpr(is_one_of<int,int,float> || is_one_of_2<T>::exec<int, float>())
{
std::cout << "same";
}
else
{
std::cout << "not same";
}
}

int main()
{
exec(32);
std::cin.get();
return 0;
}


I was thinking of templated operator ().
First one is the cleanest, but you need to know that the first param is compared to all the others.
The second one is just messy.

Do you have any idea how can i improve the design ?

Sam

unread,
Nov 24, 2018, 9:21:44 AM11/24/18
to
robert badea writes:

> Hello!
> I was messing around with C++ and wanted to do a type_trait which would
> return true if a type is one of the given types.
>

> Do you have any idea how can i improve the design ?

Something like the following. The odd "<= 0" comparison, instead of "> 0"
was needed because ">" gets parsed …differently in the context of a template
parameter.

To check if the given type occurs exactly once, just change that to "!= 1".

#include <utility>
#include <type_traits>
#include <iostream>

template<typename T, typename ...Types>
struct count_occurences {

static constexpr int how_many=((std::is_same_v<T, Types> ? 1:0) + ...);
};

template<typename T, typename first_type, typename ...Types>
using occurs_in=std::conditional_t<
count_occurences<T, first_type, Types...>::how_many <= 0,
std::false_type, std::type_type>;

int main()
{
std::cout << occurs_in<int, float, int, double, int>::value
<< std::endl;
std::cout << occurs_in<int, double>::value << std::endl;
return 0;
}

Alf P. Steinbach

unread,
Nov 24, 2018, 9:25:22 PM11/24/18
to
On 24.11.2018 15:21, Sam wrote:
> robert badea writes:
>
>> Hello!
>> I was messing around with C++ and wanted to do a type_trait which
>> would return true if a type is one of the given types.
>>
>
>> Do you have any idea how can i improve the design ?
>
> Something like the following. The odd "<= 0" comparison, instead of ">
> 0" was needed because ">" gets parsed …differently in the context of a
> template parameter.
>
> To check if the given type occurs exactly once, just change that to "!= 1".
>
> #include <utility>
> #include <type_traits>
> #include <iostream>
>
> template<typename T, typename ...Types>
> struct count_occurences {
>
>     static constexpr int how_many=((std::is_same_v<T, Types> ? 1:0) +
> ...);
> };
>
> template<typename T, typename first_type, typename ...Types>
> using occurs_in=std::conditional_t<
>     count_occurences<T, first_type, Types...>::how_many <= 0,
>         std::false_type, std::type_type>;

std::type_type?


> int main()
> {
>     std::cout << occurs_in<int, float, int, double, int>::value
>           << std::endl;
>     std::cout << occurs_in<int, double>::value << std::endl;
>     return 0;
> }
>

Cheers!,

- Alf

Kalle Olavi Niemitalo

unread,
Nov 25, 2018, 4:02:17 AM11/25/18
to
Sam <s...@email-scan.com> writes:

> The odd "<= 0" comparison, instead of "> 0" was needed because
> ">" gets parsed …differently in the context of a template
> parameter.

Or you could put parentheses around the expression, AFAIK.
0 new messages