C++ 成员函数重载 & (& 符号)
C++ member function overloading with & (ampersand)
如何选择正确的error()成员函数?我需要以某种方式投射吗?
using namespace std;
struct test
{
int error();
void error(int x);
int fun();
};
int main() {
auto f1 = &test::error; // how to pick the correct function?
auto f2 = &test::fun; // works
}
Do I need to cast somehow?
是的,您可以使用 static_cast
。
static_cast
may also be used to disambiguate function overloads by
performing a function-to-pointer conversion to specific type, as in
std::for_each(files.begin(), files.end(),
static_cast<std::ostream&(*)(std::ostream&)>(std::flush));
所以你可以:
auto f1 = static_cast<int(test::*)()>(&test::error);
auto f2 = static_cast<void(test::*)(int)>(&test::error);
您需要使用 static_cast
来消除歧义。
&test::error
不可评估,因为函数已重载。您将其分配给标记为 auto
的内容这一事实并不立即相关。
一个解决方法是根据需要使用 static_cast<int(test::*)()>(&test::error)
或 static_cast<void(test::*)(int)>(&test::error)
。
然后 auto
将起作用,因为在类型推导中不会有歧义。
您可以直接显式指定成员函数指针类型。
int (test::*f1)() = &test::error;
void (test::*f2)(int) = &test::error;
既然已经给出了答案,我将提供一个更容易理解的解决方案。如果你不想每次都写出演员表,这种情况非常适合宏:
template<class T>
using test_type_t = T test::*;
#define TEST_CAST(T, F) static_cast<test_type_t<T>>(&F)
auto f1 = TEST_CAST(void(int), test::error);
当你没有互联网来阅读丑陋的函数指针到成员语法时,这是解决方案:
auto err1 = [](test& t) { return t.error(); };
auto err2 = [](test& t, int x) { return t.error(x); };
请注意,到目前为止,您得到的闭包是类型而不是函数指针。如果你想要函数指针,如果你想在数组中存储具有相同签名的不同成员函数,这很有用,你可以通过 +
将闭包转换为(普通)函数指针(参见 here ).
据我目前所见,通过上面的内容,您可以在概念上执行任何您可以使用函数到成员指针执行的操作——当然除了调用一个恰好需要这样一个指针的例程之外。而且好看多了。
如何选择正确的error()成员函数?我需要以某种方式投射吗?
using namespace std;
struct test
{
int error();
void error(int x);
int fun();
};
int main() {
auto f1 = &test::error; // how to pick the correct function?
auto f2 = &test::fun; // works
}
Do I need to cast somehow?
是的,您可以使用 static_cast
。
static_cast
may also be used to disambiguate function overloads by performing a function-to-pointer conversion to specific type, as instd::for_each(files.begin(), files.end(), static_cast<std::ostream&(*)(std::ostream&)>(std::flush));
所以你可以:
auto f1 = static_cast<int(test::*)()>(&test::error);
auto f2 = static_cast<void(test::*)(int)>(&test::error);
您需要使用 static_cast
来消除歧义。
&test::error
不可评估,因为函数已重载。您将其分配给标记为 auto
的内容这一事实并不立即相关。
一个解决方法是根据需要使用 static_cast<int(test::*)()>(&test::error)
或 static_cast<void(test::*)(int)>(&test::error)
。
然后 auto
将起作用,因为在类型推导中不会有歧义。
您可以直接显式指定成员函数指针类型。
int (test::*f1)() = &test::error;
void (test::*f2)(int) = &test::error;
既然已经给出了答案,我将提供一个更容易理解的解决方案。如果你不想每次都写出演员表,这种情况非常适合宏:
template<class T>
using test_type_t = T test::*;
#define TEST_CAST(T, F) static_cast<test_type_t<T>>(&F)
auto f1 = TEST_CAST(void(int), test::error);
当你没有互联网来阅读丑陋的函数指针到成员语法时,这是解决方案:
auto err1 = [](test& t) { return t.error(); };
auto err2 = [](test& t, int x) { return t.error(x); };
请注意,到目前为止,您得到的闭包是类型而不是函数指针。如果你想要函数指针,如果你想在数组中存储具有相同签名的不同成员函数,这很有用,你可以通过 +
将闭包转换为(普通)函数指针(参见 here ).
据我目前所见,通过上面的内容,您可以在概念上执行任何您可以使用函数到成员指针执行的操作——当然除了调用一个恰好需要这样一个指针的例程之外。而且好看多了。