C++;转换为函数指针的转换运算符 我一直在琢磨我头脑中很简单的一个想法,但是我无法理解如何在C++中实现。

C++;转换为函数指针的转换运算符 我一直在琢磨我头脑中很简单的一个想法,但是我无法理解如何在C++中实现。,c++,function-pointers,conversion-operator,C++,Function Pointers,Conversion Operator,通常,我可以使用转换运算符声明一个类,如以下简单示例所示: class Foo { private: int _i; public: Foo( int i ) : _i(i) { } operator int( ) const { return i; } }; 所以现在我可以写一些很棒的东西,比如 int i = Foo(3); 但在我的特殊情况下,我想提供一个操作符,用于将对象转换为函数指针(例如,将Bar实例转换为int(*

通常,我可以使用转换运算符声明一个类,如以下简单示例所示:

class Foo
{
private:

    int _i;

public:

    Foo( int i ) : _i(i) { }

    operator int( ) const
    {
        return i;
    }
};
所以现在我可以写一些很棒的东西,比如

int i = Foo(3);
但在我的特殊情况下,我想提供一个操作符,用于将对象转换为函数指针(例如,将
Bar
实例转换为
int(*)(int,int)
函数指针)。以下是我最初尝试的:

class Bar
{
private:

    int (*_funcPtr)(int, int);

public:

    Bar( int (*funcPtr)(int, int) ) : _funcPtr(funcPtr) { }

    operator int(*)(int, int) ( ) const
    {
        return _funcPtr;
    }

};
但运算符函数无法编译,并生成以下错误:

expected identifier before '*' token
'<invalid-operator>' declared as a function returning a function

据我所知,我再也不能打字了。这显然让事情变得更加笨拙,但我希望还有一种方法。

使用typedef。无论如何,它更容易阅读:

class Bar
{
public:
  typedef int (*fptr_t)(int, int);

  Bar(fptr_t funcPtr) : _funcPtr(funcPtr) { }

  operator fptr_t() const
  {
    return _funcPtr;
  }

private:
  fptr_t _funcPtr;
};
[编辑]

对于您的模板案例,我不知道如何使用typedef@Kerrik给出了应该可以使用的语法的(混乱)版本。

因为您必须知道:

(*operator int() const)(int, int)
{
  return _funcPtr;
}
(再次修正。)


更新:Johannes Schraub和Luc Danton告诉我,这种语法实际上是无效的,您必须使用typedef。既然您说typedefs不是一个选项,那么这里有一个可以包装您的typedef的帮助器类:

template<typename R, typename A1, typename A2>
struct MakeFunctionType
{
  typedef R(*type)(A1, A2);
};

template<typename R, typename A1, typename A2>
operator typename MakeFunctionType<R, A1, A2>::type () const
{
    // implementation is unimportant here
}
模板
结构MakeFunctionType
{
类型定义R(*类型)(A1、A2);
};
模板
运算符typename MakeFunctionType::type()常量
{
//在这里实现并不重要
}
编辑:

由于类在构造时分配了非模板函数指针:

private:

    int (*_funcPtr)(int, int);
以后根本不可能将其转换为任何类型的函数指针

因此,我假设您指的是模板类成员运算符重载,而不是类模板成员运算符重载

模板版本:

template<typename ReturnType, typename ArgType1, typename ArgType2>
class Bar {

public:

  typedef ReturnType (*fptr_t)(ArgType1, ArgType2);

  operator fptr_t ( ArgType1 arg1, ArgType2 arg2 ) const
  {
      // implementation is unimportant here
  }

//etc...

};
模板
分类栏{
公众:
typedef ReturnType(*fptr_t)(ArgType1、ArgType2);
运算符fptr_t(ArgType1 arg1,ArgType2 arg2)常量
{
//在这里实现并不重要
}
//等等。。。
};
然后像这样使用:

//create functor to some function called myfunc
Bar::fptr_t func_ptr = Bar<int, int, int>(&myfunc); 

//call functor
int i = func_ptr(1,2); 
//为名为myfunc的函数创建functor
Bar::fptr_t func_ptr=Bar(&myfunc);
//调用函子
int i=func_ptr(1,2);

如果要使代码可读,需要使用typedef。我甚至不使用没有类型定义的函数指针,语法太可怕了

目标:

模板
运算符返回类型(*)(ArgType1,ArgType2)()常量
{
返回0;
}
路径:

//1:helper结构
模板
结构辅助程序{
类型定义R(*类型)(A0,A1);
};
//2:接线员
模板
运算符typename助手::type()常量{
返回0;
}

看看吧

GCC中的以下工作:

template<typename ReturnType, typename ArgType1, typename ArgType2>
operator decltype((ReturnType(*)(ArgType1, ArgType2)) nullptr)() const
{
    // ...
}
模板
运算符decltype((ReturnType(*)(ArgType1,ArgType2))nullptr)()常量
{
// ...
}

在C++11中,可以使用转换为任何函数,而不需要自定义类型trait
struct
s

class Bar
{
    private:


    template<typename ReturnType, typename ArgType1, typename ArgType2>
    using funcptr = ReturnType(*)(ArgType1, ArgType2);

    public:

    template<typename ReturnType, typename ArgType1, typename ArgType2>
    operator funcptr<ReturnType, ArgType1, ArgType2> ( ) const;

};
类栏
{
私人:
模板
使用funcptr=ReturnType(*)(ArgType1,ArgType2);
公众:
模板
运算符funcptr()常量;
};

要将此限制为仅
int(*)(int,int)
,我们可以使用SFINAE或
static\u assert

尝试键入定义返回类型:“typedef int(*ptr\u t)(int,int);”然后,返回类型为“operator ptr\u t()const”的对象,您缺少冒号
public:
你是在模仿boost::function吗?@jt:我在做一些类似于
boost::function
的事情,但它有一个非常独特的行为。我最初考虑使用
boost::function
,但不幸的是,我没有发现它是一个合适的选择。假设上述方法有效,有没有办法不使用typedef?只是好奇;我同意typedef更有意义。嗨,谢谢你的回答。你会看到我编辑了我的问题,因为我遗漏了一个关于我使用模板的非常重要的小细节。在这种情况下,我还能利用typedef的简单性吗?@J T-我想我在你发布答案前15分钟发布了我的答案。也是在你发表评论前5秒。(在时间上挥动鼠标,以小时:分:秒为单位查看它们)@JT,尼莫在没有阅读你的答案的情况下回答这个问题是不可能的?你为什么认为他“窃取”了你的答案?太幼稚了。这是一个带有成员函数的类模板。看起来他想要一个带有成员函数模板的真实类。@J T:aschepler完全正确。
Bar
的同一个实例必须可转换为许多不同类型的函数指针,因此模板化类不是一个选项。如果有人建议,我也不能转换为模板函子类型,它必须是一个实际的函数指针。这对他提到的模板案例没有帮助,那是在编辑之前,但这应该向前延伸,以推广到
模板(*operator T()const)(Args…
。非常感谢。函数指针语法有时会非常混乱,特别是在一个似乎没有多少人使用的场景中,并且typedef不适用。有没有可能让我解释一下为什么会这样?我的想法是,
操作符int()const
是函数名,因此它放在括号内,前面有一个星号。然后,与转换运算符一样,我们删除返回类型,因为它已经是名称的一部分。这就是语法的正确原因吗?基本原则是,始终将最终对象的标识符括在括号中,并在末尾将参数附加到另一组括号中:如果函数签名是
R(S,T)
,那么函数指针是
R(*myfp)(S,T)
(实际函数类型是
R()(S,T)
)。现在我们用
A=R(*)(S,T)
将这种思想应用到
操作符A()常数上,得到
(*?)(S,T)
,其中
???
// 1: helper structure
template <typename R, typename A0, typename A1>
struct helper {
  typedef R (*type)(A0,A1);
};

// 2: operator
template <typename R, typename A0, typename A1>
operator typename helper<R, A0, A1>::type() const {
  return 0;
}
template<typename ReturnType, typename ArgType1, typename ArgType2>
operator decltype((ReturnType(*)(ArgType1, ArgType2)) nullptr)() const
{
    // ...
}
class Bar
{
    private:


    template<typename ReturnType, typename ArgType1, typename ArgType2>
    using funcptr = ReturnType(*)(ArgType1, ArgType2);

    public:

    template<typename ReturnType, typename ArgType1, typename ArgType2>
    operator funcptr<ReturnType, ArgType1, ArgType2> ( ) const;

};