g++ 7.1.1 中的可变参数模板偏特化 "not more specialised"
Variadic template partial specialisation "not more specialised" in g++ 7.1.1
我有一个等同于 std::integer_sequence
的函数(我们还没有使用 C++14)。我还有两个助手 类 可以删除或添加前导数字。
// Sequence type
template <typename Type, Type ... Values>
struct Sequence
{
using value_type = Type;
};
// Pop a value off of the start of a sequence
template <class Class>
struct SequencePop;
template <typename Type, Type Value, Type ... Values>
struct SequencePop<Sequence<Type, Value, Values ...>>
{
using type = Sequence<Type, Values ...>;
};
// Push a value on to the start of a sequence
template <class Class, typename Class::value_type Value>
struct SequencePush;
template <typename Type, Type Value, Type ... Values>
struct SequencePush<Sequence<Type, Values ...>, Value>
{
using type = Sequence<Type, Value, Values ...>;
};
SequencePop
在我尝试过的所有编译器(g++ 6.4.1、g++ 7.1.1、clang++ 4.0.1)中都被认为是有效的。 SequencePush
无法使用 g++ 7.1.1 进行编译。报错信息如下
test.cpp:24:8: error: partial specialization ‘struct SequencePush<Sequence<Type, Values ...>, Value>’ is not more specialized than [-fpermissive]
struct SequencePush<Sequence<Type, Values ...>, Value>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:21:8: note: primary template ‘template<class Class, typename Class::value_type Value> struct SequencePush’
struct SequencePush;
g++ 7.1.1 拒绝此代码是否正确,如果是,如何判断 SequencePush
不是 "more specialised" 主模板?
应该是
template <typename Type,
Type ... Values,
typename Sequence<Type, Values ...>::value_type Value>
struct SequencePush<Sequence<Type, Values ...>, Value>
{
using type = Sequence<Type, Value, Values ...>;
};
因为 Class::value_type
和 Sequence<Type, Values ...>
中的 Type
不是 "related".
确实,通用模板 SequencePush
由一个模板参数 (Class
) 参数化,但您的专业化由两个模板参数 (Type
和 Value
) 参数化。在通用模板中,Type
不是参数,因为它是从 Class
.
推导出来的
一个有效但不令人满意的解决方案是:
template <class Class, typename Type, Type Value>
struct SequencePush;
template <typename Type, Type Value, Type ... Values>
struct SequencePush<Sequence<Type, Values ...>, Type, Value>
{
using type = Sequence<Type, Value, Values ...>;
};
我有一个等同于 std::integer_sequence
的函数(我们还没有使用 C++14)。我还有两个助手 类 可以删除或添加前导数字。
// Sequence type
template <typename Type, Type ... Values>
struct Sequence
{
using value_type = Type;
};
// Pop a value off of the start of a sequence
template <class Class>
struct SequencePop;
template <typename Type, Type Value, Type ... Values>
struct SequencePop<Sequence<Type, Value, Values ...>>
{
using type = Sequence<Type, Values ...>;
};
// Push a value on to the start of a sequence
template <class Class, typename Class::value_type Value>
struct SequencePush;
template <typename Type, Type Value, Type ... Values>
struct SequencePush<Sequence<Type, Values ...>, Value>
{
using type = Sequence<Type, Value, Values ...>;
};
SequencePop
在我尝试过的所有编译器(g++ 6.4.1、g++ 7.1.1、clang++ 4.0.1)中都被认为是有效的。 SequencePush
无法使用 g++ 7.1.1 进行编译。报错信息如下
test.cpp:24:8: error: partial specialization ‘struct SequencePush<Sequence<Type, Values ...>, Value>’ is not more specialized than [-fpermissive]
struct SequencePush<Sequence<Type, Values ...>, Value>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:21:8: note: primary template ‘template<class Class, typename Class::value_type Value> struct SequencePush’
struct SequencePush;
g++ 7.1.1 拒绝此代码是否正确,如果是,如何判断 SequencePush
不是 "more specialised" 主模板?
应该是
template <typename Type,
Type ... Values,
typename Sequence<Type, Values ...>::value_type Value>
struct SequencePush<Sequence<Type, Values ...>, Value>
{
using type = Sequence<Type, Value, Values ...>;
};
因为 Class::value_type
和 Sequence<Type, Values ...>
中的 Type
不是 "related".
确实,通用模板 SequencePush
由一个模板参数 (Class
) 参数化,但您的专业化由两个模板参数 (Type
和 Value
) 参数化。在通用模板中,Type
不是参数,因为它是从 Class
.
一个有效但不令人满意的解决方案是:
template <class Class, typename Type, Type Value>
struct SequencePush;
template <typename Type, Type Value, Type ... Values>
struct SequencePush<Sequence<Type, Values ...>, Type, Value>
{
using type = Sequence<Type, Value, Values ...>;
};