以下内容在Visual Studio上编译:
template<typename ArgType, typename ReturnType>
struct Test
{
using FunctionPointerType = std::conditional_t<
std::is_same_v<ArgType, void>
, ReturnType(*)()
, ReturnType(*)(ArgType)
>;
FunctionPointerType Func;
};
int main()
{
Test<void, char> tt;
}
但不在Linux g上编译。我得到的错误是
error : invalid parameter type ‘void’
我知道我不能在模板中使用void,这就是我使用std::conditional\u t和std::is\u same\u v的原因。
我看不出有什么不对,有人能告诉我吗?
template<typename ArgType, typename ReturnType>
struct Test
{
using FunctionPointerType = std::conditional_t<std::is_same_v<ArgType, void>, ReturnType(*)(), ReturnType(*)(ArgType)>;
FunctionPointerType Func;
};
conditional_t
需要3个参数。一个bool
和2种类型。
当ArgType为void时,右边的类型为ReturnType(*)(void)--不是合法类型。
错误立即发生。
MSVC有一个将模板视为宏的坏习惯。
类似这样:
template<class...Args>
struct Apply {
template<template<class...>class Z>
using To = Z<Args...>;
};
template<class R, class...Args>
using FunctionPtr = R(*)(Args...);
template<typename ArgType, typename ReturnType>
struct Test
{
using FunctionPointerType =
std::conditional_t<
std::is_same_v<ArgType, void>,
Apply<ReturnType>,
Apply<ReturnType, ArgType>
>::template To<FunctionPtr>;
FunctionPointerType Func;
};
构建2个包应用程序,然后根据选择的包应用程序将其中一个应用于FunctionPtr。
在这里,我避免在条件分支发生之前形成X(void)类型。
在标准中::conditional\u t
我会建议一个助手traitsfunction\u ptr\t作为替代方案
#include <type_traits>
template<typename RetType, typename... Args> struct function_ptr final {
using type = RetType(*)(Args...);
};
template <typename RetType> struct function_ptr<RetType, void> final {
using type = RetType(*)();
};
// alias helper
template<typename RetType, typename... Args>
using function_ptr_t = typename function_ptr<RetType, Args...>::type;
template<typename RetType, typename... Args>
struct Test
{
function_ptr_t<RetType, Args...> Func;
};
查看演示
请注意,我交换了类template Test中的模板参数,并将第二个模板参数设置为变量,以便测试
这意味着以下措施将起作用:
Test<char> tt1;
static_assert(std::is_same_v<char(*)(), decltype(tt1.Func)>, " are not same!");
Test<char, void> tt2;
static_assert(std::is_same_v<char(*)(), decltype(tt2.Func)>, " are not same!");
Test<void, double> tt3;
static_assert(std::is_same_v<void(*)(double), decltype(tt3.Func)>, " are not same!");
如果不是,您希望将可变参数模板参数替换为正常参数。
这并不能真正回答您的问题(为什么我的代码不起作用),但这是可行的:
template<typename ArgType, typename ReturnType>
struct Test
{
using FunctionPointerType = ReturnType(*)(ArgType);
FunctionPointerType Func;
};
template<typename ReturnType>
struct Test<void, ReturnType>
{
using FunctionPointerType = ReturnType(*)();
FunctionPointerType Func;
};
我正在编写一个小的简单程序,它使用pthreads实现了一个循环执行时间表。我首先编写了没有pthreads的程序,现在试图将参数正确地传递到pthread_create中。我知道args是: int pthread_create(pthread_t*thread,const pthread_attr_t*attr,void*(*start_routome)(void*),void*arg);
在下面的代码中,为什么模板函数的显式扩展无法编译,而条形扩展却成功编译?实时链接-https://godbolt.org/z/o8Ea49KEb 请注意,这两个函数的主体中都使用了模板参数T2,唯一的区别是已手动替换条形图的函数参数。 这个问题是在阅读了std::c条件-无效参数类型“无效”后提出的,即使在测试“无效”并试图简化问题时也是如此。
问题内容: 我正在为apache HttpClient包实现一个,如下所示: 但我希望函数不返回任何值,即。这可能吗?由于不是有效的Java类型,因此以下内容无法编译: 我想可以替换为以返回对象,但这并不是我真正想要的。 问 :是否有可能安排在这样一种方式,我可以返回此回调局面从? 问题答案: 泛型仅处理对象类。泛型不支持void和基本类型,您不能将它们用作参数化类型。您必须改用Void。 你能说
void 类型 万能类型,在需要时再具体指定;在描述一段还没有具体使用的内存时需要使用void类型。 void * 类型的指针指向的内存是尚未确定类型的,因此我们后续可以使用强制类型转换,强行将其转为各种类型。这就是void类型的最终归宿——被强制类型转换成一个具体的类型。 void * 万能指针,void * 可以指向任何类型的数据,在32位系统下,占4个字节 void* malloc(size
问题内容: 我正在玩Java 8,以了解如何发挥一流公民的作用。我有以下片段: 我想做的是使用方法引用将方法传递给方法。要编译会产生以下错误: 编译器抱怨。我不知道如何在代码的签名中指定函数接口的类型。我知道我可以简单地改变的返回类型来,然后返回。但是,在某些情况下,无法更改我想传递到其他地方的方法。有没有简单的方法可以重复使用? 问题答案: 您正在尝试使用错误的接口类型。在这种情况下,函数类型是
问题内容: 更新到xcode 8 beta 6后,出现错误 无法将’()-> Void’类型的值分配给’(()-> Void)!’ 在以下func块的第三行: 关于修复的任何建议? 问题答案: 看来您的问题与此有关: SE-0103 尝试将您的方法标头追踪到: 与往常一样,来自新Beta的诊断消息是如此混乱和不足,但是将您的媒体资源设置为非可选将为您提供更多有用的信息。