转换操作符,用于转换为函数指针

C++ Conversion operator for converting to function pointer

本文关键字:转换 函数 指针 用于 操作符      更新时间:2023-10-16

我一直在绞尽脑汁想一个在我脑海中足够简单的想法,但我不知道如何在c++中实现。

通常,我可以像下面这样用转换操作符声明一个类:

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;
    }
};

但是operator函数编译失败,生成以下错误:

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

我也尝试了上面的一些简单的变化,比如用括号括住返回类型,但是所有这些想法都失败了。

有谁知道声明转换到函数指针操作符方法的语法是什么,或者是否可以这样做?

注意:我正在使用GCC 4.5.2编译Code::Blocks。也欢迎回答涉及c++ 0x新概念的问题。

编辑

为了简化示例,我无意中遗漏了一个细节。这有点奇怪,但不是严格地返回一个int(*)(int,int)指针,转换操作符打算被模板化:

template<typename ReturnType, typename ArgType1, typename ArgType2>
operator ReturnType(*)(ArgType1, ArgType2) ( ) const
{
    // implementation is unimportant here
}

就我所知,我不再不能为这样的类型定义类型。这显然使事情变得更加笨拙,但我希望仍然有一种方法。

既然你必须知道:

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

(固定。一次。)


Update:我已经被Johannes Schraub和Luc Danton告知,这种语法实际上是无效的,并且你真的必须使用typedef。既然你说typedef不是一个选项,这里有一个帮助类可以包装你的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
}

使用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给出了应该起作用的语法的(混乱的)版本。

EDIT:

因为你的类在构造时赋值了一个非模板函数指针:

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...
};

然后这样使用:

//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); 

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

目标:

template<typename ReturnType, typename ArgType1, typename ArgType2>
operator ReturnType(*)(ArgType1, ArgType2) ( ) const
{
   return 0;
}

路径:

// 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;
}

去ideone看看吧!

在c++ 11中,可以使用别名模板转换为任何函数,而无需自定义类型特征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;
};

为了将其限制为int(*)(int, int),我们可以使用SFINAE或static_assert

以下工作在GCC中:

template<typename ReturnType, typename ArgType1, typename ArgType2>
operator decltype((ReturnType(*)(ArgType1, ArgType2)) nullptr)() const
{
    // ...
}