Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板参数在gcc6中的部分专门化中不可推断,用于在gcc5中工作的情况_C++_Templates_Gcc_Language Lawyer - Fatal编程技术网

C++ 模板参数在gcc6中的部分专门化中不可推断,用于在gcc5中工作的情况

C++ 模板参数在gcc6中的部分专门化中不可推断,用于在gcc5中工作的情况,c++,templates,gcc,language-lawyer,C++,Templates,Gcc,Language Lawyer,此代码导致gcc6出错(但在GCC4.8、5.2和clang 3.6中工作正常): 看 我已在此处向gcc提交了一份错误报告: 然而,它被标记为无效(我错误地认为)。在谓词内部使用的外部在该点上是一个具体类型,因此它不是一个非推断上下文 P>标准中有什么可以防止这是有效的C++代码吗?< /强> < p>我怀疑这是GCC 6中的一个bug,并且在CLAN 3.9中有一个错误警告(警告是奇怪的),因为警告意味着部分的专业化不会被选择,但是如果没有选择,静态断言会触发。 来自[温度等级规格匹配

此代码导致gcc6出错(但在GCC4.8、5.2和clang 3.6中工作正常):

我已在此处向gcc提交了一份错误报告:

然而,它被标记为无效(我错误地认为)。在
谓词
内部使用的
外部
在该点上是一个具体类型,因此它不是一个非推断上下文


<> P><强>标准中有什么可以防止这是有效的C++代码吗?< /强>

< p>我怀疑这是GCC 6中的一个bug,并且在CLAN 3.9中有一个错误警告(警告是奇怪的),因为警告意味着部分的专业化不会被选择,但是如果没有选择,静态断言会触发。
来自[温度等级规格匹配]:

如果 部分专门化可以从实际的模板参数列表中推导出来

我们能从
outer::inner
推断
typename outer::template inner
中的
U

从[临时扣除类型]:

如果模板参数仅在非默认情况下使用 上下文,并且未显式指定,模板参数推断失败

非推断上下文为:
-使用限定id指定的类型的嵌套名称说明符。
-[……]

但是这里指定的嵌套名称是
typename outer
,它不包含我们试图推断的类型。其他未推导的上下文都不适用。因此,演绎应该在这里成功

考虑以下等效情况:

#include <utility>

template <class >
struct outer
{
    template <class U> struct inner {};
};

template <class T>
struct bar {
    template <class U> std::false_type foo(U const&);
    template <class U> std::true_type foo(typename outer<T>::template inner<U> const&);
};


int main() {
    static_assert(decltype(bar<int>{}.foo(outer<int>::inner<double>{}))::value, "!");
}
#包括
模板
结构外部
{
模板结构内部{};
};
模板
结构条{
模板std::false_type foo(U const&);
模板std::true_type foo(typename外部::模板内部常量&);
};
int main(){
静态_断言(decltype(bar{}.foo(outer::inner{}))::value,“!”;
}
GCC6.0和Clang3.9都在没有警告的情况下编译了这段代码——但这与原始示例中的部分专门化中发生的情况是相同的

main.cpp:22:9: error: template parameters not deducible in partial specialization:
  struct predicate<typename outer<T>::template inner<U>> : std::true_type
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:22:9: note:         'U'
 ^~~~~~~~~~~~~
g++ -std=c++1y -c main.cpp
#include <utility>

template <class >
struct outer
{
    template <class U> struct inner {};
};

template <class T>
struct bar {
    template <class U> std::false_type foo(U const&);
    template <class U> std::true_type foo(typename outer<T>::template inner<U> const&);
};


int main() {
    static_assert(decltype(bar<int>{}.foo(outer<int>::inner<double>{}))::value, "!");
}