如何调用原子成员函数指针

时间:2018-07-13 19:07:25

标签: c++ function-pointers atomic

我在调用原子函数成员函数指针时遇到问题:

class test
{
   typedef void(test::*ProcessPtr)();
   std::atomic<ProcessPtr> _processPtr;  
   void process() {}
}

int main(int argc, char** argv)
{
    test t;
    t._processPtr = &test::process;
    (t.*_processPtr)();  
}

错误是:

t.cpp:238:6:错误:此范围中未声明“ _processPtr”   (t。* _ processPtr)();

不太清楚问题出在什么地方。您可以不尊重“原子”成员函数指针吗?

3 个答案:

答案 0 :(得分:1)

超级指出您需要两次使用该对象:

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 id, 'A' place UNION ALL
  SELECT 2, 'B' UNION ALL
  SELECT 1, 'C' UNION ALL
  SELECT 6, 'B' UNION ALL
  SELECT 4, 'D' UNION ALL
  SELECT 5, 'A' UNION ALL
  SELECT 6, 'C' UNION ALL
  SELECT 7, 'A' UNION ALL
  SELECT 8, 'A' UNION ALL
  SELECT 8, 'C'   
), self AS (
  SELECT arr[OFFSET(0)] place, COUNT(1) cnt
  FROM (
    SELECT ARRAY_AGG(place) arr, id
    FROM `project.dataset.table`
    GROUP BY id
    HAVING ARRAY_LENGTH(arr) = 1
  )
  GROUP BY place
), pairs AS (
  SELECT id, ARRAY_AGG(place) arr
  FROM `project.dataset.table` 
  GROUP BY id
), flat_matrix AS (
  SELECT place1, place2, COUNT(DISTINCT id) cnt
  FROM pairs, UNNEST(arr) place1, UNNEST(arr) place2
  WHERE place1 <> place2
  GROUP BY 1, 2
  UNION ALL
  SELECT place, place, cnt
  FROM self
)
SELECT place1 place,
  MAX(IF(place2 = 'A', cnt, 0)) AS A,
  MAX(IF(place2 = 'B', cnt, 0)) AS B,
  MAX(IF(place2 = 'C', cnt, 0)) AS C,
  MAX(IF(place2 = 'D', cnt, 0)) AS D 
FROM flat_matrix
GROUP BY place1
-- ORDER BY place

所以你最终得到了这个

Row place   A   B   C   D    
1   A       2   0   2   0    
2   B       0   1   1   0    
3   C       2   1   0   0    
4   D       0   0   0   1    

答案 1 :(得分:0)

_processPtr不可用。像这样public

class test
{
public:
    typedef void(test::*ProcessPtr)();
    std::atomic<ProcessPtr> _processPtr;
    void process() {};
}

使用atomic,您可以使用.store().load()进行读写。不确定它如何与指针一起工作。

答案 2 :(得分:0)

我发现了原因。这与模板参数推论有关。

如果看到模板类“ atomic”,则有一个主要的T类,并且专门研究T *。然后我比较指向函数的指针和指向函数成员的指针。 code如下所示:

#include <iostream>

template<typename T>
struct A
{ 
    static void Call(){std::cout << "Call T" << std::endl;}
};
template<typename T>
struct A<T*>
{ 
    static void Call(){std::cout << "Call T*" << std::endl;}
};

struct B {};

int main()
{
    A<void(B::*)()>::Call();
    A<void(*)()>::Call();
}

输出:

Call T
Call T*

建议改进,对函数成员使用双指针:

类测试中的更新,从std::atomic<ProcessPtr> _processPtr;std::atomic<ProcessPtr*> _processPtr;

并更新主要功能:

int main()
{
    test t;
    test::ProcessPtr d = &test::process;
    t._processPtr = &d;
    (t.*(*(t._processPtr)))();  
}