无法从类型 x 转换为类型 x
Cannot Convert From type x to type x
我得到了一个简单的类,它只是包装了一个类方法的函数调用。编译(使用Visual Studio 2013(时,我收到错误消息:
错误 2 错误 C2664: 'Sleipnir::Core::D elegate::D elegate(const Sleipnir::Core::D elegate &(' : 无法将参数 2 从 void (__cdecl *((void *const ,int &&('转换为 void (__cdecl *((void *const ,int &&(' d:\programmieren\delegate\delegate\delegate\delegate.h 29 1 Delegate
这并没有真正的帮助。
我的代码:
template<typename T>
class Delegate;
template<typename R, typename... A>
class Delegate<R(A...)>
{
using TFunc = R(*)(void* const, A&&...);
private:
Delegate(void* const obj, TFunc stub)
: _objectPtr(obj),
_stubPtr(stub){}
public:
Delegate(R(*const funcPtr)(A...))
: Delegate(nullptr, functionStub<R(*)(A...)>)
{
}
private:
template <R(*funcPtr)(A...)>
static R functionStub(void* const, A&&... args)
{
return funcPtr(::std::forward<A>(args)...);
}
private:
void* _objectPtr;
TFunc _stubPtr;
};
有人知道为什么会发生这种情况,或者如何解决它?
我发现的第一个问题是您将functionStub
引用为 functionStub<R(*)(A...)>
这是错误的,因为functionStub
采用函数指针,而不是类型。合乎逻辑的解决方法是将funcPtr
的地址作为functionStub<funcPtr>
传入,但这也会失败。我相信这是因为函数参数不是常量表达式,因此传入 funcPtr
地址的格式不正确,因为模板只能使用常量表达式和类型进行实例化。
所以我在评论中建议你应该通过将funcPtr
的签名更改为以下内容来传递给functionStub
的参数:
static R functionStub(R (*funcPtr)(A...), void* const, A... args);
随之而来的问题是函数类型与TFunc
不同。您可以通过先std::bind()
functionStub
funcPtr
来解决此问题:
: Delegate(nullptr, std::bind(&functionStub, funcPtr, placeholders::_1))
这也需要将TFunc
更改为std::function
:
using TFunc = std::function<R (void* const, A...)>;
现在我们已经摆脱了错误,但绑定只为调用放置一个参数。 A...
可以是任意数量的参数,因此我们必须使用一些机制来放置可变参数数。
可以使用 easy_bind()
方法,如此线程中所示。
: Delegate(nullptr, easy_bind(&functionStub, funcPtr))
最后,&functionStub
不能通过easy_bind()
的参数推断为std::function
类型,所以你可以为此使用make_function()
。
template <class Callable>
std::function<Callable> make_function(Callable* callable)
{
return { callable };
}
// ...
: Delegate(nullptr, easy_bind(make_function(&functionStub), funcPtr))
演示
以下行而失败:
using TFunc = R(*)(void* const, A&&...);
委托的公共构造函数服从于私有构造函数,私有构造函数需要一个指针,该函数采用 void* 后跟 int。您正在传递一个仅接受 int 的函数。
我怀疑您正在寻找一个可以处理自由函数和采用上下文参数(例如this
指针(的函数的委托。
std::function
会为您处理所有这些事情。你能用std::function<R(A&&...)>
来写你的委托吗?如果是这样,则可以使用 std::bind
来存储成员函数回调的对象指针。
现在让它工作了,感谢0x499602D2
下面是我的委托类的代码:
template <class Callable>
std::function<Callable> make_function(Callable* callable)
{
return{ callable };
}
template<typename T>
class Delegate;
template<typename R, typename... A>
class Delegate<R(A...)>
{
using TFunc = std::function<R(void* const, A...)>;
private:
Delegate(void* obj, TFunc stub)
: _objectPtr(obj),
_stubPtr(stub)
{}
public:
Delegate(R(*funcPtr)(A...))
: Delegate(nullptr, easy_bind(make_function(&functionStub), funcPtr))
{ }
template <class C>
Delegate(C* const objectPtr, R(C:: * const methodPtr)(A...))
: Delegate(objectPtr, easy_bind(make_function(&methodStub<C>), methodPtr))
{ }
template <class C>
Delegate(C* const objectPtr, R(C:: * const methodPtr)(A...) const)
: Delegate(objectPtr, easy_bind(make_function(&constMethodStub<C>), methodPtr))
{ }
public:
R operator()(A... args) const
{
return _stubPtr(_objectPtr, ::std::forward<A>(args)...);
}
private:
static R functionStub(R(*funcPtr)(A...), void* const, A... args)
{
return funcPtr(std::forward<A>(args)...);
}
template <class C>
static R methodStub(R(C::* const methodPtr)(A...), void* const objectPtr, A... args)
{
return (static_cast<C*>(objectPtr)->*methodPtr)(std::forward<A>(args)...);
}
template <class C>
static R constMethodStub(R(C::* const methodPtr)(A...) const, void* const objectPtr, A... args)
{
return (static_cast<C*>(objectPtr)->*methodPtr)(std::forward<A>(args)...);
}
private:
void* _objectPtr;
TFunc _stubPtr;
以及我如何在主课中使用它:
void test(int x)
{
std::cout << "Test - print: " << x << std::endl;
}
struct Printer
{
void print(int x){
std::cout << "Printer - print: " << x << std::endl;
}
void print2(int x) const{
std::cout << "Printer - print2: " << x << std::endl;
}
};
int main(int argc, void* args)
{
Printer printer;
Delegate<void(int)> del(&test);
Delegate<void(int)> del2(&printer, &Printer::print);
Delegate<void(int)> del3(&printer, &Printer::print2);
del(1);
del2(1);
del3(1);
}
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++中的双指针类型转换
- 逐位操作的隐式类型转换
- 模板中的类型转换
- 在 C++(和 C)中进行类型转换时明显不一致
- 字符类型转换不兼容
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- C++:用户定义的显式类型转换函数错误
- 将类指针类型转换为键时出错
- 通过引用传递参数时C++类型转换
- 在 C++ 中将一个模板类型的对象类型转换为另一个模板类型
- C++显式类型转换(C 样式强制转换)的强制表示法和static_cast的多种解释
- C++无效的函数类型转换
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何将Windows产品类型转换为名称?
- 通过构造函数方法输出的类到类类型转换是 5500 为什么不是 5555
- 事件系统:使用类型转换或联合进行继承
- 如何在参数中定义隐式类型转换的构造函数?
- 类模板实例化中的类型转换