变分函数指针转换
Variadic function pointer conversion
我正在编写一个包含许多函数对象的库,这些函数对象的类有几个operator()
重载,这些重载不依赖于类的状态,也不会改变它。现在,我试图让我的代码与许多老式的API一起工作(这不是随机的需要,我实际上必须处理这样的API),因此决定将函数对象转换为与其中一个重载对应的任何函数指针。在某个时刻,我意识到我有太多这样的函数指针运算符转换,理论上我应该能够编写一个变差转换运算符。这里有一个类实现了这样一个变差算子:
struct foobar
{
template<typename... Args>
using fptr_t = void(*)(Args... args);
template<typename... Args>
operator fptr_t<Args...>() const
{
return [](Args... args) {
// Whatever
};
}
};
正如您所看到的,我使用lambda到函数指针的转换来实现转换运算符,这不是问题,因为我拥有的每个函数对象都是无状态的。目标是能够使用如下类:
int main()
{
void(*foo)(int) = foobar();
void(*bar)(float, double) = foobar();
}
g++使用预期的语义编译此代码没有问题。然而,clang++以模板替换失败错误拒绝了它:
main.cpp:21:11: error: no viable conversion from 'foobar' to 'void (*)(int)' void(*foo)(int) = foobar(); ^ ~~~~~~~~ main.cpp:11:5: note: candidate function [with Args = int] operator fptr_t<Args...>() const ^ 1 error generated.
注意,只要不涉及可变模板,clang++就不会有这样的转换运算符的问题。如果我使用单个模板参数,那么编译代码就没有问题。现在,编译器应该接受还是拒绝上面的代码?
lambda只有在不捕获的情况下才能转换为函数指针,因此您的代码应该可以工作。这在标准5.1.2/p6 Lambda表达式[expr.prim.Lambda](Emphasis Mine)中得到了证明:
没有的非泛型lambda表达式的闭包类型lambda捕获具有公共非虚拟非显式常量转换函数到指针,指向具有C++语言链接(7.5)的函数与闭包类型的函数相同的参数和返回类型呼叫接线员此转换函数返回的值应为调用时与调用闭包类型的函数调用运算符。
所以我会把它作为一个CLANG错误来归档
作为CLANG的解决方案,您可以将其转换为std::function
,如下所示:
struct foobar
{
template<typename... Args>
using fptr_t = void(*)(Args... args);
template<typename... Args>
operator std::function<void(Args...)>() const
{
return [](Args... args) {
//...
};
}
};
int main()
{
std::function<void(int)> f1 = foobar();
std::function<void(double, float)> f2 = foobar();
f1(1);
f2(2.0, 1.0f);
}
实时演示
- 转换指针引用的字符串
- 无法向上转换指针到指针参数
- 混合转换指针和引用
- 堆栈对象的强制转换指针
- 基类到派生模板类的强制转换指针,而不知道类型
- 删除类型转换指针的最佳方法
- 管理到本机值类转换:强制转换指针是否安全?
- 转换指针类型
- 为什么函数不能正确强制转换指针(从基类到派生类)
- 当我们递增下面的类型转换指针时会发生什么?
- 类型强制转换指针构造函数调用
- 如何转换(指针向量)-->(指向指针数组的指针)
- 如何从类功能转换指针
- 在C++对象中:我应该使用父类强制转换指针,还是应该使用实际类本身进行强制转换
- Delphi中的类型转换指针添加
- C++分段错误(核心转储)错误 - 强制转换指针/将函数值返回到线程
- 以C++和运算符优先级键入指向数组成员的强制转换指针
- C++动态强制转换指针的内存清理
- 转换指针和引用的好处
- 在c++中转换指针