c++ - SFINAE 模板的优先顺序?

标签 c++ sfinae

我正在尝试实现采用版本参数的模板化结构。

这是一个简化的例子:

template<int Version, class Enable = void>
struct Foo
{
};

template<int Version, class Enable = void>
struct Bar
{
};

/* Base Version of Foo */
template<int Version>
struct Foo<Version, typename enable_if<(Version > 0)>::type>
{
    int i;
};

/* Base Version of Bar */
template<int Version>
struct Bar<Version, typename enable_if<(Version > 0)>::type>
{
    Foo<Version> foo;
    float f;
};

/* Version 2 of Bar */
template<int Version>
struct Bar<Version, typename enable_if<(Version >= 2)>::type>
{
    Foo<Version> foo;
    float f;
    int extraParam;
};

使用这种方法,当我使用“Bar<2>”时会出现歧义,因为 2 满足基本版本的条件(版本 > 0)和版本 2 的条件(版本 >= 2)。

我可以将基础更改为要求“版本 > 0 && 版本 < 2”,但我希望避免在任何地方都必须这样做。有没有更好的方法告诉编译器“使用最高匹配版本”给定模板?

最佳答案

使用 example linkdyp 提供,我能够用递归解决这个问题。

#include <iostream>
#include <type_traits>

using namespace std;

template<int Version>
struct Foo
{
    constexpr static bool is_valid = false;
};

template<int Version>
struct Bar
{
    constexpr static bool is_valid = false;
};

struct ValidVersion { constexpr static bool is_valid = true; };

/* Base Version of Foo */
template<>
struct Foo<0> : ValidVersion
{
    int i;
};

/* Base Version of Bar */
template<>
struct Bar<0> : ValidVersion
{
    Foo<0> foo;
    float f;
};

/* Version 2 of Bar */
template<>
struct Bar<2> : ValidVersion
{
    Foo<2> foo;
    float f;
    int extraParam;
    int extraParam2;
};

template<template<int V> class _Tp, int Version>
struct VersionSelectorImpl
{
    template<class T>
    struct wrap { using type = T; };
    using type = typename std::conditional<_Tp<Version>::is_valid, wrap<_Tp<Version>>, VersionSelectorImpl<_Tp, Version-1>>::type::type;
};

template<template<int V> class _Tp, int Version>
using VersionSelector = typename VersionSelectorImpl<_Tp, Version>::type;

int main() {
    cout << "sizeof(<Bar, 1>): " << sizeof(VersionSelector<Bar, 1>) << '\n';
    cout << "sizeof(<Bar, 2>): " << sizeof(VersionSelector<Bar, 2>) << '\n';
}

输出:

sizeof(<Bar, 1>): 12
sizeof(<Bar, 2>): 16

关于c++ - SFINAE 模板的优先顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24003698/

相关文章:

c++ - 使用 ctypes.cdll.LoadLibrary 从 Python 加载库时 ELF header 无效

c++ - 为什么 g++ 将函数报告为具有类型 int ()()?

c++ - 在构造函数中实例化对象时的C++类成员作用域

c++ - 如何实现 "either nested type or void"特征?

c++ - SFINAE 优雅地检查 "template template class"(在模板参数中)

c++ - boost odeint 包示例代码中出现错误 C2309

python - 为什么 2019 年我们仍然不能使用 ctypes 从 Python 调用 C++?

c++ - 使用以下 has_member 函数时 SFINAE 无法正常工作的原因是什么?

c++ - 当模板重载可用时,检查函数的自定义重载是否存在

c++ - 使用 enable_if 和 SFINAE 时,函数参数类型推导(标准容器,例如 vector )失败