在处理类成员函数指针时,我们可以使用以下语法在对象实例上调用函数:
struct X {
void foo();
};
X x; // Instance
auto f = &X::foo; // Member function pointer
(x.*f)(); // Call function f on x
Run Code Online (Sandbox Code Playgroud)
当有一个实例的原始指针时,语法是这样的:
X *xptr = new X();
(xptr->*f)();
Run Code Online (Sandbox Code Playgroud)
这很好地遵循了静态函数调用的类比:
x.foo();
x->foo();
Run Code Online (Sandbox Code Playgroud)
但是,当我有一个类的智能指针时,这不起作用:
unique_ptr<X> xsptr(new X());
(xsptr->*f)(); // g++: error: no match for 'operator->*' in 'xsptr ->* f'
Run Code Online (Sandbox Code Playgroud)
我通过首先应用取消引用运算符,然后使用以下.语法调用来解决此问题:
((*xsptr).*f)();
Run Code Online (Sandbox Code Playgroud)
这是有多丑?
编译器是否应该拒绝上面的箭头语法?因为通常(静态调用函数时),它调用operator ->. 不应该->*也只是打电话operator ->吗?
编译器错误部分地回答了这个问题:错误读作我们可以重载operator ->*以调用解除引用对象上的成员函数指针,但unique_ptr事实并非如此。但这带来了更多的问题。如果语言需要这样做,为什么智能指针不这样做?是不是打算不这样做,因为它引入了其他问题?为什么我们必须写这个操作符,而不是隐式调用返回的对象上的成员函数指针->?(因为这是写作时的行为xsptr->foo() …
c++ member-function-pointers smart-pointers operator-overloading c++11
我试图fn根据某个constexpr值选择一个成员。然后我尝试调用选定的函数,但是我收到了关于如何fn使用不正确的语法调用成员的错误。
error: must use '.*' or '->*' to call pointer-to-member function in
'S::SelectedGetter<&S::fn1, &S::fn2>::fn (...)', e.g. '(... ->*
S::SelectedGetter<&S::fn1, &S::fn2>::fn) (...)'
18 | return SelectedGetter<&S::fn1, &S::fn2>::fn();
Run Code Online (Sandbox Code Playgroud)
我试图称之为“正确”但失败了。最后我使用的是std::invoke,但我想知道这是否可以在没有 的情况下完成std::invoke,只使用“原始”C++ 语法。
#include <algorithm>
#include <type_traits>
static constexpr int number = 18;
struct S
{
using GetterFn = uint32_t(S::*)() const;
uint32_t fn1()const {
return 47;
}
uint32_t fn2() const {
return 8472;
}
template <GetterFn Getter1, GetterFn Getter2>
struct SelectedGetter
{
static constexpr …Run Code Online (Sandbox Code Playgroud) 在C++中,是否可以为成员函数指针定义排序顺序?似乎运算符<未定义.此外,施放到void*是违法的.
class A
{
public:
void Test1(){}
void Test2(){}
};
int main()
{
void (A::* const one)() = &A::Test1;
void (A::* const two)() = &A::Test2;
bool equal = one == two; //Equality works fine.
bool less = one < two; //Less than doesn't.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
我正在使用定义接口的库:
template<class desttype>
void connect(desttype* pclass, void (desttype::*pmemfun)());
Run Code Online (Sandbox Code Playgroud)
我有一个小的层次结构
class base {
void foo();
};
class derived: public base { ... };
Run Code Online (Sandbox Code Playgroud)
在一个成员函数中derived,我想打电话
connect(this, &derived::foo);
Run Code Online (Sandbox Code Playgroud)
但它似乎&derived::foo实际上是一个成员函数指针base; gcc吐了出来
error: no matching function for call to ‘connect(derived* const&, void (base::* const&)())’
Run Code Online (Sandbox Code Playgroud)
我可以通过明确地this转向来解决这个问题base *.但为什么编译器不能匹配调用desttype = base(因为derived *可以隐式转换为base *)?
另外,为什么是 &derived::foo不是一个成员函数指针derived?
假设我有
struct X {
~X() {}
};
Run Code Online (Sandbox Code Playgroud)
我X::~X()在C++ 03中获取成员函数指针的类型是什么?
我不想实际调用它,只是在SFINAE中使用来确定是否存在给定类型的析构函数.
考虑在c ++中实现例程的三种方法:通过仿函数,成员函数和非成员函数.例如,
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class FOO
{
public:
void operator() (string word) // first: functor
{
cout << word << endl;
}
void m_function(string word) // second: member-function
{
cout << word << endl;
}
} FUNCTOR;
void function(string word) // third: non-member function
{
cout << word << endl;
}
Run Code Online (Sandbox Code Playgroud)
现在考虑一个模板函数来调用上面的三个函数:
template<class T>
void eval(T fun)
{
fun("Using an external function");
}
Run Code Online (Sandbox Code Playgroud)
FOO::m_function通过eval 调用的正确方法是什么?
我试过了:
FUNCTOR("Normal call"); // OK: call …Run Code Online (Sandbox Code Playgroud) c++ templates member-function-pointers functor template-function
我正在关注这个例子.但是当我编译时,它会返回一个错误:
无效使用非静态成员函数
在线
void(Machine:: *ptrs[])() =
{
Machine::off, Machine::on
};
Run Code Online (Sandbox Code Playgroud)
我尝试添加static到 void on();在类
class Machine
{
class State *current;
public:
Machine();
void setCurrent(State *s)
{
current = s;
}
static void on(); // I add static here ...
static void off(); // and here
};
Run Code Online (Sandbox Code Playgroud)
但它抱怨说
在静态成员函数中使用成员Machine :: current无效
你能帮我解决这个问题吗?
我正在尝试为模板类编写一个函数,该函数接受一个参数,该参数是大类私有数据中成员类的函数指针.当您调用该成员时,它会在较小的类上调用该函数.(令人困惑的权利?)为了证明,我在这里有一个非工作的例子:
#include <vector>
#include <iostream>
using namespace std;
template <typename T, typename C>
struct MyClass {
template <typename F, typename... A>
auto call_me(F func, A... args) { // pass in the function we want to call
return (mContainer.*func) (args...); // call the function supplied by
// the parameter on the private member data
}
C mContainer; // this will be private in my actual code
};
int main() {
MyClass<int, std::vector<int> > test;;
cout << test.call_me(&std::vector<int>::size) << endl; // works …Run Code Online (Sandbox Code Playgroud) c++ templates member-function-pointers function-pointers variadic-templates
如何将const成员函数作为非const成员函数传递给模板?
class TestA
{
public:
void A() {
}
void B() const {
}
};
template<typename T, typename R, typename... Args>
void regFunc(R(T::*func)(Args...))
{}
void test()
{
regFunc(&TestA::A); // OK
regFunc(&TestA::B); // ambiguous
}
Run Code Online (Sandbox Code Playgroud)
不想添加类似的内容:
void regFunc(R(T::*func)(Args...) const)
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
我知道构造函数没有返回类型。虽然我想知道,构造函数的类型是什么?构造函数有类型吗?
我试过了
struct A { A() {} };
template <typename A> struct foo;
int main() { foo< decltype(&A::A) > f; }
Run Code Online (Sandbox Code Playgroud)
得到错误(gcc)
prog.cc: In function 'int main()':
prog.cc:5:32: error: taking address of constructor 'constexpr A::A(A&&)'
5 | int main() { foo< decltype(&A::A) > f; }
| ^
prog.cc:5:35: error: template argument 1 is invalid
5 | int main() { foo< decltype(&A::A) > f; }
| ^
Run Code Online (Sandbox Code Playgroud)
...好吧,我不能接受地址。同样这失败了:
int main() { foo< decltype(A::A) > f; }
Run Code Online (Sandbox Code Playgroud)
与
prog.cc: In function 'int …Run Code Online (Sandbox Code Playgroud) c++ ×10
templates ×4
c++11 ×2
c++03 ×1
c++20 ×1
casting ×1
class ×1
constructor ×1
destructor ×1
functor ×1
name-lookup ×1
pointers ×1
std-invoke ×1