我似乎找不到将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?
答案 0 :(得分: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...> {}
答案 1 :(得分:7)
我担心这不可能,因为模板包很笨重。但是,您可以打包。
// 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
};