g++ 7.1.1 中的可变参数模板部分特化"not more specialised"

Variadic template partial specialisation "not more specialised" in g++ 7.1.1

本文关键字:not specialised more 板部 参数 变参 g++      更新时间:2023-10-16

>我有一个等价物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不比主模板"更专业"?

它应该是

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_typeSequence<Type, Values ...>Type不是"相关的"。

事实上,通用模板SequencePush由一个模板参数(Class(参数化,但您的专业化由两个(TypeValue(参数化。在常规模板中,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 ...>;                          
};     

演示