我正在尝试实现带有版本参数的模板化结构。
这是一个简化的例子:
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&lt; 2&gt;”时存在歧义,因为2满足基本版本的条件(版本&gt; 0)和版本2条件(版本&gt; = 2)。
我可以更改基数以要求“版本&gt; 0&amp;&amp;版本&lt; 2”,但我希望避免在任何地方都这样做。是否有更好的方法告诉编译器“使用最高匹配版本”给定模板?
答案 0 :(得分:2)
使用example link提供的dyp,我能够通过递归来解决问题。
#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(&lt; Bar,1&gt;):12
sizeof(&lt; Bar,2&gt;):16