标签: member-pointers

通过成员指针访问受保护的成员:这是一个黑客?

我们都知道protected从基类指定的成员只能从派生类自己的实例访问.这是标准的一个特性,这已在Stack Overflow上多次讨论:

但似乎有可能用成员指针来解决这个限制,因为用户chtz 向我展示:

struct Base { protected: int value; };
struct Derived : Base
{
    void f(Base const& other)
    {
        //int n = other.value; // error: 'int Base::value' is protected within this context
        int n = other.*(&Derived::value); // ok??? why?
        (void) n;
    }
};
Run Code Online (Sandbox Code Playgroud)

coliru现场演示

为什么这可能,它是一个想要的功能或实施中的某个地方或标准的措辞?


从评论中出现了另一个问题:如果Derived::f用实际调用Base,是不确定的行为?

c++ protected access-specifier member-pointers language-lawyer

52
推荐指数
2
解决办法
3777
查看次数

为什么声明顺序对于将成员函数指针作为模板参数传递很重要?

看看这段代码:

template <typename T, void (T::*pfn)()> struct Testee {};

class Tester
{
private:
    void foo() {}
public:
    using type_t = Testee<Tester, &Tester::foo>;    
};
Run Code Online (Sandbox Code Playgroud)

它成功编译g++ -std=c++14 -Wall -Wextra.

但是,当我改变的顺序footype_t,发生错误:

$ cat test.cpp
template <typename T, void (T::*pfn)()> struct Testee {};

class Tester
{
public:
    using type_t = Testee<Tester, &Tester::foo>;
private:
    void foo() {}
};

int main()
{
}

$ g++ -std=c++14 -Wall -Wextra -pedantic test.cpp
test.cpp:6:36: error: incomplete type ‘Tester’ used in nested name specifier …
Run Code Online (Sandbox Code Playgroud)

c++ templates member-pointers

23
推荐指数
1
解决办法
1185
查看次数

成员函数指针

如果C++ FAQ Lite中的以下内容为真:"函数名称衰减到指向函数的指针"(因为数组名称衰减为指向其第一个元素的指针); 为什么我们必须加入&符号?

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = &Fred::f;
Run Code Online (Sandbox Code Playgroud)

而不只是:

typedef  int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = Fred::f;
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,Fred :: f是一个函数,可以衰减到指向该函数的指针.

我希望这个问题不是那么愚蠢.

c++ member-function-pointers member-pointers

16
推荐指数
1
解决办法
1421
查看次数

为什么不允许从VirtualBase ::*转换为Derived ::*?

昨天,我和我的同事不确定为什么语言禁止这种转换

struct A { int x; };
struct B : virtual A { };

int A::*p = &A::x;
int B::*pb = p;
Run Code Online (Sandbox Code Playgroud)

甚至演员都没有帮助.如果基本成员指针是虚拟基类,为什么标准不支持将基本成员指针转换为派生成员指针?

相关的C++标准参考:

类型"指向Bcv类型成员的指针"的prvalue T,其中B是类类型,可以转换为类型为"指向Dcv类型成员的指针"的prvalue T,其中D是派生类(第10条)B.如果B不可访问(第11条),模糊(10.2)或虚拟(10.1)基类D,或虚拟基类的基类D,则需要进行此转换的程序是不正确的.

函数和数据成员指针都会受到影响.

c++ virtual-inheritance member-pointers

15
推荐指数
1
解决办法
247
查看次数

我可以将成员数据指针分配给派生类型吗?

这可能最好用示例代码显示.以下无法使用g ++编译:

struct Base {
};

struct Derived : public Base {
};

struct Container {
    Derived data_;
};

int main(void) {
    Base Container::*ptr = &Container::data_;
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:invalid conversion from 'Derived Container::*' to Base Container::*'.语言不允许这样做吗?这是编译器错误吗?我使用了错误的语法吗?

请帮忙!

关于为什么我要这样做的一些背景:我有几个我想主要用作派生类型的成员数据,但我希望能够通过一些常用代码填充它们.数据将以任意顺序出现,并有一个字符串标签,我将用它来选择要填充的相应成员数据.我计划创建一个std::map<std::string, Base Container::*>通过公共接口为每个成员分配数据.我想避免使用巨型if else构造来找到正确的成员数据.

c++ member-pointers

13
推荐指数
1
解决办法
351
查看次数

匹配继承的成员函数的类型

我有以下剪切的代码,不编译.

#include <iostream>

struct A {
    void foo() {}
};

struct B : public A {
    using A::foo;
};

template<typename U, U> struct helper{};

int main() {
    helper<void (A::*)(), &A::foo> compiles;
    helper<void (B::*)(), &B::foo> does_not_compile;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它自&B::foo解析后不编译&A::foo,因此无法与提议的类型匹配void (B::*)().由于这是SFINAE模板的一部分,我用它来检查一个非常具体的接口(我强制使用特定的参数类型和输出类型),我希望这可以独立于继承,同时保持检查的可读性.

我尝试的内容包括:

  • 抛出论证的第二部分:

    helper<void (B::*)(), (void (B::*)())&B::foo> does_not_compile;

    遗憾的是,这并没有帮助,因为第二部分现在不被认为是一个常量表达式,并且失败了.

  • 我已经尝试为变量分配引用,以便检查它.

    constexpr void (B::* p)() = &B::foo; helper<void (B::* const)(), p> half_compiles;

    这个代码被clang 3.4接受,但g ++ 4.8.1拒绝它,我不知道谁是对的.

有任何想法吗?

编辑:由于许多评论要求更具体的问题版本,我会在这里写:

我正在寻找的是一种明确检查类是否尊重特定接口的方法.此检查将用于验证模板化函数中的输入参数,以便它们遵守这些函数所需的合约,以便在类和函数不兼容的情况下(即类型特征类型的检查)预先停止编译.

因此,我需要能够验证我请求的每个成员函数的返回类型,参数类型和数量,常量等.最初的问题是我用来验证匹配的更大模板的检查部分.

c++ match member-pointers sfinae c++11

13
推荐指数
2
解决办法
646
查看次数

嵌套数据成员指针 - 不可能?

愚蠢的简化代码示例没有做任何有用的事情,而是对数据成员指针的两个后续分配.第一个分配工作,第二个分配给出编译器错误.大概是因为它是一个嵌套的成员.

问题是:是否真的不可能让成员指针指向嵌套成员,或者我错过了任何花哨的语法?

struct Color {
    float Red;
    float Green;
    float Blue; };


struct Material {
    float Brightness;
    Color DiffuseColor; };


int main() {
    float Material::* ParamToAnimate;
    ParamToAnimate = &Material::Brightness;       // Ok
    ParamToAnimate = &Material::DiffuseColor.Red; // Error! *whimper*
    return 0; }
Run Code Online (Sandbox Code Playgroud)

ATM我通过使用字节偏移和大量演员来解决.但这很难看,我最好使用那些成员指针.

是的,我知道之前肯定会出现这个问题(几乎与任何问题一样).是的,我事先搜查过但发现没有令人满意的答案.

谢谢你的时间.

c++ member-pointers

10
推荐指数
2
解决办法
1094
查看次数

C++ 指向成员函数的指针,替换 __closure

不久前,Borland 在他们的 BCB 环境中引入了 C++ 语言的扩展。这个扩展是一个 __closure 关键字。问题是,是否可以用普通 C++ 或 C++11 实现此类功能?如果您不熟悉 __closure 关键字,下面的代码在注释中提供了解释。

提前致谢!托雷诺

#include <stdio.h>

// __closure keyword is used here !
typedef void (__closure * MemberCallback)(int x, int y, int z);

class A
{
    private:

        MemberCallback callback;


    public:

        A() : callback(NULL)
        {
        }

        void setCallback(MemberCallback newCallback)
        {
            callback = newCallback;
        }

        void call(int x, int y, int z)
        {
            if(callback)
                callback(x, y, z);
            else
                printf("NOT SET(%i, %i, %i)\n", x, y, z);
        }
};

class B
{
    public: …
Run Code Online (Sandbox Code Playgroud)

c++ closures pointers member-pointers c++11

8
推荐指数
1
解决办法
2833
查看次数

成员函数指针返回相同类型的成员函数指针

我想在C++中声明一个成员函数指针,它返回相同的成员函数指针类型

这不起作用:

class MyClass { 
public: 
        typedef FunctionPtr (MyClass::*FunctionPtr)(); 
}
Run Code Online (Sandbox Code Playgroud)

有人知道解决方案吗?

c++ declaration return-type member-pointers

7
推荐指数
2
解决办法
823
查看次数

template&lt;typename T, T&gt; 是什么意思?

我正在阅读这个史前元程序示例来检测一个类是否支持成员查找。(或任何其他成员)。

template<typename T>
class DetectFind
{
    struct Fallback { int find; }; 
    struct Derived : T, Fallback { };

    template<typename U, U> struct Check;

    typedef char Yes[1];  
    typedef char No[2]; 

    template<typename U>
    static No& func(Check<int Fallback::*, &U::find>*);

    template<typename U>
    static Yes& func(...);

public:
    typedef DetectFind type;
    enum { value = sizeof(func<Derived>(0)) == sizeof(Yes) };
};

int main()
{
    std::cout << DetectFind<std::vector<int> >::value << std::endl;
    std::cout<< DetectFind<std::set<int> >::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

直觉上我确实理解这背后的目的,但如果有人让我在 10 天后从头开始写同样的东西,我可能会失败。
原因是我不完全理解这里使用的句法和语言延伸。
有人可以解释以下语法的含义吗?

  1. Check<int Fallback::*, &U::find>* (我知道它试图在这里从 SFIANE …

c++ templates member-pointers sfinae

7
推荐指数
2
解决办法
95
查看次数