C++14 与 C++17 的部分专业化差异?

2024-03-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++预览都给出编译错误。

对于 clang,结果是:

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 预览的结果是:

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 的一些细微差别,这会导致 clang 和 VC++ 拒绝 C++17 中的代码,即使 gcc 认为它是正确的。有谁知道这里谁是正确的以及为什么代码不能在 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++ 的错误,并指出取消注释行和注释其他三行确实可以正常工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++14 与 C++17 的部分专业化差异? 的相关文章

  • C++ 维护子类对象的混合集合

    如果我在这里错过了一个相当基本的概念 我很抱歉 但我正在尝试弄清楚如何维护多个类类型的集合 所有类类型都派生自同一个父类 并且在检索它们时仍然可以访问它们的特定于子类的方法从集合中 作为上下文 我有一个基类 BaseClass 和许多类 例
  • 如何从 C# 中的 dataTable.Select( ) 查询中删除单引号?

    所以我有一个经销商名称列表 我正在我的数据表中搜索它们 问题是 一些傻瓜必须被命名为 Young s 这会导致错误 drs dtDealers Select DealerName dealerName 所以我尝试替换字符串 尽管它对我不起作
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 为什么在 WebApi 上下文中在 using 块中使用 HttpClient 是错误的?

    那么 问题是为什么在 using 块中使用 HttpClient 是错误的 但在 WebApi 上下文中呢 我一直在读这篇文章不要阻止异步代码 https blog stephencleary com 2012 07 dont block
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp
  • 如何将十六进制字符串转换为无符号长整型?

    我有以下十六进制值 CString str str T FFF000 如何将其转换为unsigned long 您可以使用strtol作用于常规 C 字符串的函数 它使用指定的基数将字符串转换为 long long l strtol str

随机推荐