C++11 GCC的部分专门化失败

C++11 GCC的部分专门化失败,c++11,gcc,c++14,template-specialization,c++17,C++11,Gcc,C++14,Template Specialization,C++17,在回答了这个问题之后,我决定深入研究这个问题,找到一个最小的、可复制的、有相同错误的例子 假设我有以下主模板,我想将其专门化为std::vector,如下所示: #include <vector> #include <iostream> template<typename T, typename T::value_type v> struct foo; template<typename T, T v> struct foo<std::v

在回答了这个问题之后,我决定深入研究这个问题,找到一个最小的、可复制的、有相同错误的例子

假设我有以下主模板,我想将其专门化为
std::vector
,如下所示:

#include <vector>
#include <iostream>

template<typename T, typename T::value_type v>
struct foo;

template<typename T, T v>
struct foo<std::vector<T>, v> {
    static constexpr T value = v;
};

int main() {
    std::cout << foo<std::vector<int>, 32>::value << std::endl;
    return 0;
}
本示例适用于GCC 6.3.0,至少适用于GCC 4.5.4


有人能确认这是一个编译器错误吗?GCC 7.1.0是否有任何变通方法可以让我的示例发挥作用?

最近的标准修改了规则“专业化应比主模板更专业化”。尝试分别使用类模板(和专门化)的模板参数以及参数类型
foo
foo
创建函数模板重载,并查看编译器是否抱怨歧义。如果是这样,那么GCC至少看起来是一致的。也可以和叮当声相比。。。我认为GCC在这里是正确的:
foo
没有推导出参数
foo
,因为
T
可以是任何东西。而
foo
(其中
v
的类型为
typename std::vector::value_type
)无法推断参数
foo
(其中
v
的类型为
anything
),因为非类型参数的类型不同(对于最后一部分,我找不到一个明确的引语……但是由于
anywhere
是一种虚构的符号类型,我看不出它如何能够弥合类型差异)。但是,此示例使用GCC8编译,仅在wandbox上使用GCC7时失败:。因此,他们似乎认为类型差异无关紧要,并推断出
v
。Clang也接受重载集并成功调用。@Johanneschaub litb,我刚刚使用
foo
foo
尝试了我的示例,尽管
T
可以是任何东西,它适用于Wandbox中列出的所有GCC版本:。作为一种解决方法,
template struct foo{…};
适用于GCC 7.0。不知怎的,似乎很难确定
T
std::vector::value\u type
是同一个版本。该标准最近修改了该规则“专用化应比主模板更专用。”。尝试使用类模板(和专用化)的模板参数创建函数模板重载分别使用参数类型
foo
foo
,并查看编译器是否抱怨歧义。如果是这样,那么GCC至少看起来是一致的。另外,与Clang比较……我认为GCC在这里是正确的:
foo
不会推断参数
foo
,因为
T
可以anything.And
foo
(其中
v
的类型为
typename std::vector::value_type
)无法推断参数
foo
(其中
v
的类型为
anything
),因为非类型参数的类型不同(对于最后一部分,我找不到一个明确的引语……但是由于
anywhere
是一种虚构的符号类型,我看不出它如何能够弥合类型差异)。但是,此示例使用GCC8编译,仅在wandbox上使用GCC7时失败:。因此,他们似乎认为类型差异无关紧要,并推断出
v
。Clang也接受重载集并成功调用。@Johanneschaub litb,我刚刚使用
foo
foo
尝试了我的示例,尽管
T
可以是任何东西,它适用于Wandbox中列出的所有GCC版本:。作为一种解决方法,
template struct foo{…};
适用于GCC 7.0。不知怎的,似乎很难确定
T
std::vector::value\u type
是同一个。
prog.cc:8:12: error: partial specialization 'struct foo<std::vector<T>, v>' is not more specialized than [-fpermissive]
     struct foo<std::vector<T>, v> {
            ^~~~~~~~~~~~~~~~~~~~~~
prog.cc:5:12: note: primary template 'template<class T, typename T::value_type v> struct foo'
     struct foo;
            ^~~