我一直在反对一个简单易懂的想法,但我无法弄清楚如何用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;
}
};
但是运算符函数无法编译,生成了这些错误:
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
}
据我所知,我不再无法输入这样的类型。这显然使事情变得更加笨拙,但我希望还有一种方法。
答案 0 :(得分:17)
因为你必须知道:
(*operator int() const)(int, int)
{
return _funcPtr;
}
(固定。再次。)
更新: 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
}
答案 1 :(得分:4)
使用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给出了应该有效的语法(杂乱)版本。
答案 2 :(得分:1)
修改强>
由于您的类在构造时分配了非模板函数指针:
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);
答案 3 :(得分:1)
如果您想使代码可读,则需要才能使用typedef。我甚至没有使用函数指针而没有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上查看!
答案 4 :(得分:0)
以下在GCC中有效:
template<typename ReturnType, typename ArgType1, typename ArgType2>
operator decltype((ReturnType(*)(ArgType1, ArgType2)) nullptr)() const
{
// ...
}
答案 5 :(得分:0)
在C ++ 11中,可以使用alias template转换为任何函数,而无需使用自定义类型特征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
。