gpt4 book ai didi

c++ - clang 与 gcc 和 msvc 中方法指针的模板

转载 作者:太空狗 更新时间:2023-10-29 21:46:24 25 4
gpt4 key购买 nike

我有这个功能:

template <typename T, void (T::*pf)()>
void call(T& t)
{
(t.*pf)();
}

如果我有课foo使用具有适当签名的方法(比如 bar )我可以这样调用它 call<foo, &foo::bar>();没关系。但是,如果 barconst gcc 和 msvc 很乐意在这样调用时编译它 call<const foo, &foo::bar>() . Clang 提示第二个模板参数无效。当我把 const在模板参数 ( void (T::*pf)() const ) 中,所有树都会编译它。

现在,这不是一个大问题,但如果我不必编写这个可恶的 const,我的代码会变得更加清晰在模板参数中。

所以问题基本上是:标准对此有何规定?这是一个 clang 错误,还是 gcc 和 msvc 只是让它滑动,因为它们很酷?

PS 这是一个完整的重现程序的链接:http://codepad.org/wDBdGvSN

最佳答案

方法的 const 特性是其“签名”的一部分。因此,定义和使用指向成员的指针的正确方法是:

R (Obj::*)(Args)       // for non-const member
R (Obj::*)(Args) const // for const member

请注意,const 成员可以在非 const 对象上调用,而 R (const Obj::*)(Args) 则不是这种情况。

解决此问题的一种方法是通过定义“调用包装器”来抽象此类函数指针:

template<typename O, void (O::* f)()>
struct NonConstFunc
{
static void call(O* o)
{
(o->*f)();
}
};

template<typename O, void (O::* f)() const>
struct ConstFunc
{
static void call(O* o)
{
(o->*f)();
}
};

然后,您可以按以下方式使用它(此处进行抽象):

template<typename Obj, typename Function>
void call(Obj* o)
{
Function::call(o);
}

有一个live example here .

这只是主要思想。您可以通过自动检测方法是否为 const 来扩展它,而无需更改用户代码。

关于c++ - clang 与 gcc 和 msvc 中方法指针的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15293584/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com