C ++ 14与C ++ 17的部分专业化差异? [英] Partial specialization difference for C++14 versus C++17?

查看:75
本文介绍了C ++ 14与C ++ 17的部分专业化差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码:

#include <iostream>
#include <cstddef>
#include <type_traits>

template <class T,T (*g)(),bool (*s)(T),class NP = std::nullptr_t,class dummy = void>  struct pfun;

template <class T,T (*g)(),bool (*s)(T)>
struct pfun<T,g,s,std::nullptr_t,typename std::enable_if<g != nullptr && (std::is_const<T>::value || s == nullptr)>::type>
  {
  pfun() {std::cout << "class pfun<T,g,s,std::nullptr_t,typename std::enable_if<g != nullptr && (std::is_const<T>::value || s == nullptr)>::type>\n";} 
  };

template <class T,T (*g)(),bool (*s)(T),class NP>
struct pfun<T,g,s,NP,typename std::enable_if<g == nullptr && s != nullptr>::type>
  {
  pfun() {std::cout << "class pfun<T,g,s,NP,typename std::enable_if<g == nullptr && s != nullptr>::type>";}
  };
 
template <class T,T (*g)(),bool (*s)(T),class NP>
struct pfun<T,g,s,NP,typename std::enable_if<g != nullptr && s != nullptr>::type>
  {
  pfun() {std::cout << "class pfun<T,g,s,NP,typename std::enable_if<g != nullptr && s != nullptr>::type>";}
  };

template <class T,T (*g)(),bool (*s)(T)>
struct pfun<T,g,s,std::nullptr_t,typename std::enable_if<g == nullptr && s != nullptr>::type> 
  {
  pfun() {std::cout << "class pfun<T,g,s,std::nullptr_t,typename std::enable_if<g == nullptr && s != nullptr>::type>";}
  };

template <class T,T (*g)(),bool (*s)(T)>
struct pfun<T,g,s,std::nullptr_t,typename std::enable_if<g != nullptr && s != nullptr>::type> 
  {
  pfun() {std::cout << "class pfun<T,g,s,std::nullptr_t,typename std::enable_if<g != nullptr && s != nullptr>::type>";}
  };
  
char const gl_r_const_ch('c');
char const gl_fun_r_read_const_ch()  { return gl_r_const_ch; }
pfun<char const,&gl_fun_r_read_const_ch,nullptr> pf_read_const_ch;

int main() { return 0; }

以C ++ 14级别gcc-10.2进行编译时,clang-linux-11.0,VC ++-14.2和VC ++-14.2预览版在编译/链接时没有问题.但是,当以C ++ 17级别进行编译时,尽管gcc-10.2仍然可以毫无问题地编译代码,但是clang,VC ++和VC ++ Preview都带来了编译错误.

When compiling at the C++14 level gcc-10.2, clang-linux-11.0, VC++-14.2, and VC++-14.2 preview has no problem compiling/linking. But when compiling at the C++17 level, while gcc-10.2 still compiles the code without any problem, clang, VC++, and VC++ preview all give compiling errors.

对于c声,结果是:

test_pmf.cpp:39:50: error: implicit instantiation of undefined template 'pfun<const char, &gl_fun_r_read_const_ch, nullptr, nullptr_t, void>'
pfun<char const,&gl_fun_r_read_const_ch,nullptr> pf_read_const_ch;
                                                 ^
test_pmf.cpp:5:95: note: template is declared here
template <class T,T (*g)(),bool (*s)(T),class NP = std::nullptr_t,class dummy = void>  struct pfun;

对于VC ++ 14.2和VC ++ 14.2预览,结果为:

For VC++14.2 an VC++14.2 preview the result is:

test_pmf.cpp
test_pmf.cpp(39): error C2079: 'pf_read_const_ch' uses undefined struct 'pfun<const char,gl_fun_r_read_const_ch,0x0,std::nullptr_t,void>'

代码对我来说似乎很好,但也许有人知道C ++ 17的细微差别,即使gcc接受它是正确的,这也会导致clang和VC ++拒绝C ++ 17中的代码.有人知道谁是正确的,为什么代码无法在C ++ 17中编译?

The code seems fine to me but maybe someone knows some nuance of C++17 which causes both clang and VC++ to reject the code in C++17, even though gcc accepts it as correct. Does anybody know who is correct here and why the code would not compile in C++17 ?

推荐答案

我将以上内容简化为:

#include <iostream>
#include <cstddef>
#include <type_traits>

template <class T,T (*g)(),bool (*s)(T),class NP = std::nullptr_t,class dummy = void>  struct pfun;

template <class T,T (*g)(),bool (*s)(T)>
struct pfun<T,g,s,std::nullptr_t,typename std::enable_if<g != nullptr && (std::is_const<T>::value || s == nullptr)>::type>
  {
  pfun() {std::cout << "class pfun<T,g,s,std::nullptr_t,typename std::enable_if<g != nullptr && (std::is_const<T>::value || s == nullptr)>::type>\n";} 
  };
  
char const gl_r_const_ch('c');
char const gl_fun_r_read_const_ch()  { return gl_r_const_ch; }
pfun<char const,&gl_fun_r_read_const_ch,nullptr> pf_read_const_ch;

// char gl_r_ch('c');
// char gl_fun_r_read_ch()  { return gl_r_ch; }
// pfun<char,&gl_fun_r_read_ch,nullptr> pf_read_ch;

int main() { return 0; }

并将其报告为clang和vc ++的错误,并指出取消注释行并注释其他三行确实可以正常工作.

and reported it as a bug to clang and vc++, noting that uncommenting the commented lines and commenting the other three lines does work correctly.

这篇关于C ++ 14与C ++ 17的部分专业化差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆