basyuni
basyuni

Reputation: 3

Is there a way to declare a type alias based on whether i get a single or multiple template arguments? Preferably without specialization

So this code block obviously doesn't work(conditional out of statement scope:D); what i want is, if only a single template argument is passed, i set the type alias to that type, if multiple are passed i set it as a tuple of the passed in types:

 template <typename... Args>
 struct KeyPolicy
 {
     if constexpr (sizeof...(Args) == 1)
     {
         using KeyType = std::tuple_element_t<0, std::tuple<Args...>>;
     }
     else
     {
         using KeyType = std::tuple<Args...>;
     }
 
     static KeyType getKey(const Args&... args)
     {
         return KeyType{args...};
     }
 };

Upvotes: 0

Views: 145

Answers (2)

Jarod42
Jarod42

Reputation: 217810

You can use std::conditional, something like:

template <typename... Ts>
struct KeyPolicy
{
    using KeyType = std::conditional_t<sizeof...(Ts) == 1,
                                       std::tuple_element_t<0, std::tuple<Ts...>,
                                       std::tuple<Ts...>
                                      >;
 
     static KeyType getKey(const Ts&... args)
     {
         return KeyType{args...};
     }
 };

Care, both sides are evaluated, so you might sometime trick to do "lazy" evaluation.

Note: It currently fails with empty pack as std::tuple_element_t<0, std::tuple<>> is ill formed.

Upvotes: 1

Bas Groothedde
Bas Groothedde

Reputation: 402

Yes, you can use std::conditional from <type_traits> for this.

#include <type_traits>
#include <tuple>

template <typename... Args>
struct KeyPolicy {
    using KeyType = std::conditional_t<
        sizeof...(Args) == 1, // condition
        std::tuple_element_t<0, std::tuple<Args...>>, // if true
        std::tuple<Args...> // if false
    >;

    static KeyType getKey(const Args&... args)
    {
        return KeyType{args...};
    }
};

Upvotes: 1

Related Questions