当前位置: 首页 > 知识库问答 >
问题:

具有可变模板类的SFINAE?

钱跃
2023-03-14

对于将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;
};

我如何使用它来专门化NoRef的情况下,引用存在于arg包?

共有2个答案

祁博涛
2023-03-14

我担心这是不可能的,因为模板包很笨重。不过,你可以打包。

// 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...> {};

现在我们可以使用包了

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

template <typename... Args>
class NoRef<Pack<Args...>, false> {
    // no reference in Args... here
};
翟永春
2023-03-14

这不使用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...> {}
 类似资料:
  • 我很难弄清楚如何使用适当的模板化参数调用setValue函数。在ParameterBase抽象基类中不可能有模板化的参数。非常感谢任何帮助。 附注。我没有使用boost::any的灵活性。

  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 考虑下面的代码 在第三个例子中,我知道模板推导不能发生,这就是为什么要显式指定模板参数。但是为什么没有从到

  • 以下代码是递归变量函数重载的教科书示例。在clang和GCC中,它编译干净,返回36(如预期的那样): 然而,这里有一个小小的修改。它在模板定义中使用依赖类型,而不是直接使用模板参数: 它使用GCC 5.2编译并运行,但使用clang 3.8时失败: 我的问题是双重的。 是否真的有效使用参数包 typename 模式将范围解析运算符应用于包的每个成员,如 ? clang 相对于标准是否正确,或者这

  • 请考虑以下定义和演绎指南: 如果我尝试使用显式模板参数实例化 ,代码将正确编译: 如果我试图通过演绎指南实例化< code>foo... > G7产生编译器错误: clang 5 爆炸: wandbox上的实例 虽然clang肯定被窃听了(报告为问题#32673),但g拒绝我的代码是正确的吗?我的代码格式错误吗?

  • 我需要声明一个可以存储不同类型容器的类。也就是说,如果它能处理STD::Bitset和STD::Array就好了。但是,这两个类需要不同的模板参数······是否可能(以及如何)使用模板化模板类和可变模板来声明此类类? 示例(但错误):