8

可変個引数テンプレートクラスでSFINAEを使用するための適切なソリューションが見つからないようです。

参照が気に入らない可変個引数テンプレートオブジェクトがあるとしましょう。

template<typename... Args>
class NoRef
{
    //if any of Args... is a reference, this class will break
    //for example:
    std::tuple<std::unique_ptr<Args>...> uptrs;
};

そして、引数パックに参照が含まれているかどうかを便利にチェックするクラス:

template<typename T, typename... Other>
struct RefCheck
{
    static const bool value = std::is_reference<T>::value || RefCheck<Other...>::value;
};
template<typename T>
struct RefCheck<T>
{
    static const bool value = std::is_reference<T>::value;
};

これを使用して、参照がargパックに存在する場合にNoRefを特殊化するにはどうすればよいですか?

4

2 に答える 2

9

これはSFINAEを使用しませんが、基本的には意図したとおりに機能します。

template<bool Ref, typename... Args>
class NoRef_;

template<typename... Args>
class NoRef_<false, Args...>
{
    std::tuple<std::unique_ptr<Args>...> uptrs;
};
template<typename... Args>
class NoRef_<true, Args...>
{
    // contains reference
};

template<typename... Args>
using NoRef = NoRef_<RefCheck<Args...>::value, Args...>;

// alternative from Nawaz

template<typename... Args> struct NoRef : NoRef_<RefCheck<Args...>::value, Args...> {}
于 2012-12-19T09:18:37.623 に答える
8

テンプレートパックは扱いにくいため、これをそのまま使用することはできません。ただし、パックをパックすることはできます。

// Used to transport a full pack in a single template argument
template <typename... Args> struct Pack {};

身元調査を適応させます:

template <typename T, typename... Other>
struct RefCheck
{
    static const bool value = std::is_reference<T>::value
                           || RefCheck<Other...>::value;
};

template <typename T>
struct RefCheck<T>
{
    static const bool value = std::is_reference<T>::value;
};

template <typename... Args>
struct RefCheck<Pack<Args...>>: RefCheck<Args...> {};

そして今、私たちは:を使用することができPackます

template <typename P, bool = RefCheck<P>::value> class NoRef;

template <typename... Args>
class NoRef<Pack<Args...>, false> {
    // no reference in Args... here
};
于 2012-12-19T09:18:08.877 に答える