组合模板参数形成函数签名时无效的 void 参数

2024-02-15

尝试获取两个回调的签名并生成使用它们每个返回值的回调签名。

给定回调A and B=> 生成F

例 1) A:int(char) B: double(bool)=> F:双精度(整数)

例 2) A:void(char) B: void(int)=> F:无效(无效)

实例化回调时遇到奇怪的编译器错误void作为参数:

error: invalid parameter type ‘void’

有问题的代码

template<class Signature>
struct my_func;

template<class Ret, class... Args>
struct my_func<Ret(Args...)>
{};

template<class FuncA, class FuncB>
struct my_fwd;

template<class ORet, class... OArgs,
         class Ret, class... Args>
struct my_fwd<
  my_func<ORet(OArgs...)>,
  my_func<Ret(Args...)>
  >
{
  my_func< ORet(Ret) > func;  // <--- error
};

int main(int, char *[])
{
  my_func<void(int)> my3;  // (1)
  my_func<void(void)> my4; // (2)
  my_func<void()> my5;     // (3)

  my_fwd< decltype(my3), my_func<void(char)> > fwd1; // (4)
  my_fwd< decltype(my3), decltype(my4) > fwd2;       // (5)

  return 0;
}

虽然实例化没有问题my_func's with void (1), (2), (3), the my_fwd's (4) (5)失败了,我想了解为什么。

解决办法?!

我找到了一个解决方法,通过专门化my_fwd for Ret == void:

// with this specialization i can avoid the error
template<class ORet, class... OArgs,
         class... Args>
struct my_fwd<
  my_func<ORet(OArgs...)>,
  my_func<void(Args...)>
  >
{
  my_func< ORet() > func;
};

Question

编译器尝试在内部实例化有什么区别

my_fwd< my_func<void(int)>, my_func<void(char)> >:

-> my_func<void(void)> func

and

the manualmain() 中的版本:my_func<void(void)> my4?

Was the void专业化correct修复方法?备择方案?我显然对专业化和代码重复不感兴趣。


实例化与实例化之间的区别void作为模板参数并手动编写void (void)是后者做的not产生一个函数,取 avoid范围。清单(void)因为函数的参数是一个语法结构,其含义与()。这是 C 的遗产,其中()表示“参数未指定”并且(void)意思是“没有参数”。 C++ 删除了未指定的情况,并且()意思是“没有参数”。

然而,模板实例化发生在语法处理之后很长时间,因此实际上尝试实例化函数的参数(T) with T = void导致错误。正如尝试声明一个函数将是一个错误(std::remove_reference<decltype(std::declval<void*>())>::type) (i.e. void实际上拼写为一种类型)。

恐怕解决这个问题的唯一方法确实是专门从事void.

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

组合模板参数形成函数签名时无效的 void 参数 的相关文章

  • 是否有可能劫持标准输出

    我正在尝试使用 C 重定向 Windows XP 上已运行进程的标准输出 我知道如果我自己生成进程 我可以做到这一点 但对于这个应用程序 我更喜欢一个 监听器 我可以附加到另一个进程 这在纯 Net 中可能吗 如果不可能 在 Win32 中
  • ASP.NET Web 应用程序中的身份验证遇到问题

    我正在尝试对从登录页面登录我的 Web 应用程序的用户进行身份验证 我正在使用本教程 http support microsoft com kb 301240作为指南 它几乎准确地解释了我希望做什么 但是当我输入用户名和密码时 验证不起作用
  • 深拷贝和动态转换 unique_ptr

    假设我有一个如下所示的类 class A virtual A class B public A class C public A 我还有一个 unique ptr 向量 它是这样声明的 std vector
  • NDK 应用 onDestroy 清理 - 如何 DetachCurrentThread

    因此 如果我们连接 我们必须在完成后分离线程 对吗 JNIEnv get jni env JNIEnv res JAVA VM gt GetEnv void res JNI VERSION 1 6 Using cached JavaVM J
  • 在没有 epsilon 的情况下可以将浮点数与 0.0 进行比较吗?

    我知道 要比较两个浮点值 需要使用一些 epsilon 精度 因为它们并不精确 但是 我想知道是否存在边缘情况 我不需要那个 epsilon 特别是 我想知道这样做是否总是安全的 double foo double x if x lt 0
  • 组合框下拉位置

    我有一个最大化的表单 其中包含 500px 的组合框控件 停靠在右上角 Width 尝试打开组合框后 列表的一半超出了屏幕 如何强制列表显示在表单中 棘手的问题 我找不到解决这个问题的好办法 只是一个解决方法 添加一个新类并粘贴如下所示的代
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • Linq 合并列表

    我的课 public class Foo public int A get set public List
  • 对作为函数参数传递的指针使用删除

    删除作为函数参数传递的指针是否可以 并且合法 如下所示 include
  • 在c#中获取没有时间的日期

    我的表上有一列 缺勤日期时间 日期 当我想要获取包含日期的行时 它返回 0 行 这是我的 C 代码 DateTime ClassDate DateTime Parse lblDate Content ToString var Abs dbs
  • 如何让XmlReader读取C#中的属性?

    我有一个 XML Stream 其中包含以下 XML 内容
  • C#:自定义转换为值类型

    是否可以将自定义类转换为值类型 这是一个例子 var x new Foo var y int x Does not compile 是否有可能实现上述情况 我需要超载一些东西吗Foo 您将必须重载强制转换运算符 public class F
  • valgrind 在 Raspberry Pi 上返回未处理的指令

    我最近一直在尝试在运行 Debian GNU Linux7 0 喘息 的树莓派 型号 b 上使用 valgrind 来调试分段错误 每次我在编译的 C 程序上运行 valgrind 时 都会得到类似以下内容的信息 disInstr arm
  • Type.GetInterfaces() 仅适用于声明的接口

    首先 像这样的问题有很多 也许有些OP甚至在问同样的问题 问题是这些问题的答案 无论是否接受 都没有真正回答这个问题 至少我找不到 如何确定类直接声明的接口 而不是由父级或声明的接口继承的接口 e g interface I interfa
  • Xcode 7 调试器不会中断内联标头函数

    过去五年我一直在各种 C 项目中使用 Xcode 没有出现这个问题 今天 我打开了一个较旧的项目 大约 2 年前 并尝试通过在该函数中放置一个活动断点来调试头文件中的内联函数 由于某种原因 调试器不会中断此代码 但是 如果我在调用该函数的
  • 使用多态对象数组进行 JSON 反序列化

    我在涉及多态对象数组的 JSON 反序列化方面遇到问题 我已经尝试过记录的序列化解决方案here https stackoverflow com questions 5186973 json serialization of array w
  • 卸载程序

    我正在尝试使用此代码卸载程序 但它似乎不起作用 我尝试过其他答案 但似乎也不起作用 有人可以帮助我吗 我正在尝试按给定名称 displayName 卸载该程序 例如 我给出 displayName Appname 那么此代码应该从我的计算机
  • 具有四个 && 的 LINQ Where 子句

    我正在尝试在Where 子句中创建一个带有4 个参数的LINQ 查询 这是一个 Windows 8 应用程序项目 我正在使用 SQLite 数据库 SQLite 实现 https github com praeclarum sqlite n
  • 从对列表创建邻接列表类型结构

    在 C 中 我有 class Pair int val1 int val2 我有一个来自以下来源的配对列表 List
  • 如何在c#中创建多线程

    我需要监听机器中的所有串行端口 假设我的机器有 4 个串行端口 我必须创建 4 个线程并开始分别使用附加线程监听每个端口 我使用此代码来获取我的机器中的端口数量 private SerialPort comPort new SerialPo

随机推荐