Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
231 views
in Technique[技术] by (71.8m points)

c++ - How can I make this variadic template code shorter using features from C++14 and C++1z?

This is a code snippet that I am going to use in order to check whether the variadic template types are unique:

template <typename...>
struct is_one_of;

template <typename F>
struct is_one_of<F> {
    static constexpr bool value = false;
};

template <typename F, typename S, typename... T>
struct is_one_of<F, S, T...> {
    static constexpr bool value =
        std::is_same<F, S>::value || is_one_of<F, T...>::value;
};

template <typename...>
struct is_unique;

template <>
struct is_unique<> {
    static constexpr bool value = true;
};

template <typename F, typename... T>
struct is_unique<F, T...> {
    static constexpr bool value =
        is_unique<T...>::value && !is_one_of<F, T...>::value;
};

int main() {
    constexpr bool b = is_unique<bool, int, double>::value;
    constexpr bool c = is_unique<int, char, int>::value;
    static_assert(b == true && c == false, "!");
}

Is there any way to make this code shorter and/or more concise using features introduced in C++14 and C++1z? Or is there a better way to achieve the same effect using the new features?

In the case of C++1z I mean: features that are already available in the newest versions of Clang and GCC.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

We recently added std::disjunction to the C++1z draft, which can be used for is_one_of (and it stops instantiating as soon as it finds a match, see the link for more details):

template <typename F, typename... T>
  using is_one_of = std::disjunction<is_same<F, T>...>;

This is already implemented in GCC trunk. For older versions of GCC you can use the implementation detail __or_ instead:

template <typename F, typename... T>
  using is_one_of = std::__or_<is_same<F, T>...>;

Or implement disjunction by hand using C++11 facilities, as shown at the end of the proposal linked to above.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...