Error capture of non variable

lamdba и "error: capture of non-variable 'type::v'"


lamdba и «error: capture of non-variable ‘type::v'»

От:

niXman

Ниоткуда

https://github.com/niXman
Дата:  17.07.12 13:22
Оценка:

3 (1)

привет.

следующий код. успешно компилится компиляторами версии 4.6.х, но выдает сабжевую ошибку при компиляции с использованием 4.7.1.

struct type {
   type() {
      [&v]() {}
   }
   
   int v;
};

int main() {
}

http://liveworkspace.org/code/fd17b80f11a60b81214bce4bedf99df9

код писал с использованием 4.6.3. кода написал дико много. при попытке собрать на 4.7.1 — получил тону ошибок %)

подскажите. как все же правильно захватывать переменные члены класса?

спасибо.

пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)


Re: lamdba и «error: capture of non-variable ‘type::v'»

От:

niXman

Ниоткуда

https://github.com/niXman
Дата:  17.07.12 13:37
Оценка:

так же, для всех лябмдов( %) ) выдается еще и ошибка: error: ‘this’ was not captured for this lambda function

код:

#include <iostream>

struct type {
   type() {
      [&v]() {std::cout<<v<<std::endl;}
   }
   
   int v;
};

int main() {
}

http://liveworkspace.org/code/01ae6ebb0527d6d900635e4bfa356c41

на 4.6.3 все гуд.

пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)


Re: lamdba и «error: capture of non-variable ‘type::v'»

От:

Abyx

Россия

 
Дата:  17.07.12 13:38
Оценка:

Здравствуйте, niXman, Вы писали:

X>подскажите. как все же правильно захватывать переменные члены класса?

[this]

либо [=] — тогда this тоже захватится

In Zen We Trust


Re[2]: lamdba и «error: capture of non-variable ‘type::v'»

От:

niXman

Ниоткуда

https://github.com/niXman
Дата:  17.07.12 13:42
Оценка:

Здравствуйте, Abyx, Вы писали:

A>

A>[this]
A>

т.е. захватывать мемберы нельзя? только this?

пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)


Re[2]: lamdba и «error: capture of non-variable ‘type::v'»

От:

niXman

Ниоткуда

https://github.com/niXman
Дата:  17.07.12 13:44
Оценка:

а this разве по умолчанию не захватывается?

пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)


Re[3]: lamdba и «error: capture of non-variable ‘type::v'»

От:

Abyx

Россия

 
Дата:  17.07.12 13:47
Оценка:

Здравствуйте, niXman, Вы писали:

X>Здравствуйте, Abyx, Вы писали:


A>>

A>>[this]
A>>



X>т.е. захватывать мемберы нельзя? только this?

захватывать можно только переменные, а не поля объектов.

точно так же для `Foo* x;` нельзя написать `[&x->some]`

In Zen We Trust


Re[4]: lamdba и «error: capture of non-variable ‘type::v'»

От:

niXman

Ниоткуда

https://github.com/niXman
Дата:  17.07.12 13:49
Оценка:

Здравствуйте, Abyx, Вы писали:

A>захватывать можно только переменные, а не поля объектов.


A>точно так же для `Foo* x;` нельзя написать `[&x->some]`

ясно.

зы
наговнокодил тыщи строк кода. да здравствует рефак!

пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)


Re[3]: lamdba и «error: capture of non-variable ‘type::v'»

От:

Abyx

Россия

 
Дата:  17.07.12 13:49
Оценка:

Здравствуйте, niXman, Вы писали:

X>а this разве по умолчанию не захватывается?

нет.
посмотрите стандарт, там [this] отдельно описан в синтаксисе языка

In Zen We Trust

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

Created attachment 26999 [details]
the preprocessed file

~/gcc-test$ g++-4.7.0 -o test -v -save-temps ItemIncGroup.cpp 
Using built-in specs.
COLLECT_GCC=g++-4.7.0
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/i686-pc-linux-gnu/4.7.0/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ../configure --program-suffix=-4.7.0
Thread model: posix
gcc version 4.7.0 (GCC) 
COLLECT_GCC_OPTIONS='-o' 'test' '-v' '-save-temps' '-shared-libgcc' '-mtune=generic' '-march=pentiumpro'
 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.7.0/cc1plus -E -quiet -v -D_GNU_SOURCE ItemIncGroup.cpp -mtune=generic -march=pentiumpro -fpch-preprocess -o ItemIncGroup.ii
ignoring nonexistent directory "/usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/i686-pc-linux-gnu
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/../../../../include/c++/4.7.0/backward
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/include
 /usr/local/include
 /usr/local/lib/gcc/i686-pc-linux-gnu/4.7.0/include-fixed
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-o' 'test' '-v' '-save-temps' '-shared-libgcc' '-mtune=generic' '-march=pentiumpro'
 /usr/local/libexec/gcc/i686-pc-linux-gnu/4.7.0/cc1plus -fpreprocessed ItemIncGroup.ii -quiet -dumpbase ItemIncGroup.cpp -mtune=generic -march=pentiumpro -auxbase ItemIncGroup -version -o ItemIncGroup.s
GNU C++ (GCC) version 4.7.0 (i686-pc-linux-gnu)
	compiled by GNU C version 4.7.0, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++ (GCC) version 4.7.0 (i686-pc-linux-gnu)
	compiled by GNU C version 4.7.0, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c256e2cdb5a4ae96bd7afc48ca236d31
ItemIncGroup.cpp: In member function ‘bool CItemIncGroup::SetIncrementalCountMax()’:
ItemIncGroup.cpp:7:38: error: capture of non-variable ‘CItemIncGroup::m_TotalIncrementalCount’ 
In file included from ItemIncGroup.cpp:3:0:
ItemIncGroup.h:17:18: note: ‘long int CItemIncGroup::m_TotalIncrementalCount’ declared here

Notes: Changing the type of m_pItemIncGroup from CItemInc to int will allow the code to compile. This code compiled with gcc 4.6.1.


Comment 1


Jonathan Wakely



2012-03-26 15:43:59 UTC

It works if you remove the parentheses, which also makes the code valid C++ (currently it relies on a GNU extension that allows a variable array size for a parenthesised new expression, you get a warning with -pedantic or -Wvla)

It seems that there's some interaction between the C++11 lambda parsing and the GNU extension


Comment 2


Steffen Möller



2012-05-25 10:33:51 UTC

Hello, I have something similar in the OpenMM code (https://simtk.org/home/openmm), with no ()s following the "new" as in


template <typename T>
struct CUDAStream : public SoADeviceObject
{
    unsigned int    _length;
    unsigned int    _subStreams;      # line 68
    unsigned int    _stride;
    T**             _pSysStream;
    T**             _pDevStream;
    T*              _pSysData;
    T*              _pDevData;
    std::string     _name;
    CUDAStream(int length, int subStreams = 1, std::string name="");
    CUDAStream(unsigned int length, unsigned int subStreams = 1, std::string name="");
    CUDAStream(unsigned int length, int subStreams = 1, std::string name="");
    CUDAStream(int length, unsigned int subStreams = 1, std::string name="");
    virtual ~CUDAStream();
    void Allocate();
    void Deallocate();
    void Upload();
    void Download();
    void CopyFrom(const CUDAStream<T>& src);
    void Collapse(unsigned int newstreams = 1, unsigned int interleave = 1);
    T& operator[](int index);
};

[...]

template <typename T>
void CUDAStream<T>::Allocate()
{
    cudaError_t status;
    _pSysStream =   new T*[_subStreams];                      # line 125
    _pDevStream =   new T*[_subStreams];
    _pSysData =     new T[_subStreams * _stride];

    status = cudaMalloc((void **) &_pDevData, _stride * _subStreams * sizeof(T));
    RTERROR(status, (_name+": cudaMalloc in CUDAStream::Allocate failed").c_str());

    for (unsigned int i = 0; i < _subStreams; i++)
    {
        _pSysStream[i] = _pSysData + i * _stride;
        _pDevStream[i] = _pDevData + i * _stride;
    }
}

for which 4.6.3 (Debian 4.6.3-5) happily crunches but 4.7 (Debian 4.7.0-9) gives me

cd /homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/obj-x86_64-linux-gnu/platforms/cuda/sharedTarget && /usr/local/bin/c++   -DOpenMMCuda_EXPORTS -DOPENMM_LIBRARY_NAME=OpenMM -DOPENMM_MAJOR_VERSION=1 -DOPENMM_MINOR_VERSION=0 -DOPENMM_BUILD_VERSION=0 -DOPENMM_SVN_REVISION="exported" -DOPENMM_COPYRIGHT_YEARS="2008" -DOPENMM_AUTHORS="Peter.Eastman" -O3 -DNDEBUG -fPIC -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/cuda/src -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/cuda/./include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/src -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/libraries/validate/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/reference/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/libraries/lbfgs/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/libraries/sfmt/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/libraries/lepton/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/libraries/quern/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/libraries/jama/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/olla/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/openmmapi/include -I/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/./include    -DOPENMMCUDA_BUILDING_SHARED_LIBRARY -o CMakeFiles/OpenMMCuda.dir/__/__/__/src/cuda/kApplyConstraints.cu_OpenMMCuda_generated.cpp.o -c /homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/obj-x86_64-linux-gnu/src/cuda/kApplyConstraints.cu_OpenMMCuda_generated.cpp
/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/cuda/./src/kernels//cudatypes.h: In member function ‘virtual void CUDAStream<T>::Allocate()’:
/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/cuda/./src/kernels//cudatypes.h:125:27: error: capture of non-variable ‘CUDAStream<T>::_subStreams’ 
/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/cuda/./src/kernels//cudatypes.h:68:10: note: ‘unsigned int CUDAStream<T>::_subStreams’ declared here
/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/cuda/./src/kernels//cudatypes.h:126:27: error: capture of non-variable ‘CUDAStream<T>::_subStreams’ 
/homeLvm/moeller/alioth/debichem/experimental/openmm-4.1/platforms/cuda/./src/kernels//cudatypes.h:68:10: note: ‘unsigned int CUDAStream<T>::_subStreams’ declared here
make[3]: *** [platforms/cuda/sharedTarget/CMakeFiles/OpenMMCuda.dir/__/__/__/src/cuda/kApplyConstraints.cu_OpenMMCuda_generated.cpp.o] Error 1


Thanks and regards,

Steffen


Comment 3


Jonathan Wakely



2012-05-25 11:09:37 UTC

N.B. I've changed the Summary, the "non-variable" in the diagnostic refers to a non-automatic variable, in this case a data member, which isn't allowed in a lamdba capture. The problem is not that the error says a member variable is a non-variable, it's that a new-expression is mistaken for a lambda-expresion.


(In reply to comment #2)
> Hello, I have something similar in the OpenMM code
> (https://simtk.org/home/openmm), with no ()s following the "new" as in

Please provide a minimal, complete example, those snippets do not allow your report to be reproduced or confirmed.  This seems to be equivalent but works fine:

template <typename T>
struct CUDAStream
{
    unsigned int    _subStreams;
    T**             _pSysStream;
    void Allocate();
};

template <typename T>
void CUDAStream<T>::Allocate()
{
    _pSysStream =   new T*[_subStreams];
}


Comment 4


Steffen Möller



2012-05-29 10:33:36 UTC

Hello, this took me a while.

It seems like the problem is in (or in the interaction with) nvcc, the NVidia compiler. For that you program for the graphics card and the host processor at the same time. The .cu files indicate such files that are not meant to be seen by the regular compiler at a first sight. It then generates preprocessed files for gcc to digest.

$ rm -f t.cu_OpenMMCuda_generated.cpp; /usr/bin/nvcc t.cu -cuda -o t.cu_OpenMMCuda_generated.cpp && g++ -c t.cu_OpenMMCuda_generated.cpp
t.cu: In member function ‘void CUDAStream<T>::Allocate()’:
t.cu:12:27: error: capture of non-variable ‘CUDAStream<T>::_subStreams’ 
t.cu:4:10: note: ‘unsigned int CUDAStream<T>::_subStreams’ declared here

$ cat t.cu
template <typename T>
struct CUDAStream
{
    unsigned int    _subStreams;
    T**             _pSysStream;
    void Allocate();
};

template <typename T>
void CUDAStream<T>::Allocate()
{
    _pSysStream =   new T*[_subStreams];
}


The NVCC-generated code now has the ()s again:

# 9 "t.cu"
template< class T> void
# 10 "t.cu"
CUDAStream< T> ::Allocate()
# 11 "t.cu"
{
# 12 "t.cu"
(_pSysStream) = (new (T *[_subStreams]));
# 13 "t.cu"
}

4.6 crunges it, 4.7 does not. Sounds like we should prepare an email to NVidia. Anybody with any direct contacts?

Thanks

Steffen


Comment 5


Steffen Möller



2012-05-29 11:31:04 UTC

$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2012 NVIDIA Corporation
Built on Thu_Apr__5_00:24:31_PDT_2012
Cuda compilation tools, release 4.2, V0.2.1221

as shipping with Debian unstable in package version 4.2.9-1.


Comment 6


Jonathan Wakely



2012-05-29 11:55:06 UTC

Anything to do with the cuda compiler is irrelevant here, this report is for a GCC bug not for other programs, even if they generate code that triggers the bug.

Anyway, I'm confirming this, here's a reduced testcase that produces a slightly different eror, due to using a global instead of a data member:

struct A { };

extern int n;

void f()
{
    A** p = new (A*[n]);
}

Accepted by 4.6 and earlier, rejected by 4.7 and later

$ g++-4.7 -c t.cc
t.cc: In function 'void f()':
t.cc:7:21: warning: capture of variable 'n' with non-automatic storage duration [enabled by default]
t.cc:3:5: note: 'int n' declared here


N.B. 4.5 says

t.cc: In function ‘void f()’:
t.cc:7:19: warning: lambda expressions only available with -std=c++0x or -std=gnu++0x

But that was fixed for 4.6


Comment 7


Jonathan Wakely



2012-05-29 11:59:26 UTC

(In reply to comment #6)
> N.B. 4.5 says
> 
> t.cc: In function ‘void f()’:
> t.cc:7:19: warning: lambda expressions only available with -std=c++0x or
> -std=gnu++0x
> 
> But that was fixed for 4.6

I tested 4.5.2, that should be fixed in 4.5.3, see Bug 46159 and its dup Bug 47651


Comment 8


Jason Merrill



2012-06-01 21:19:26 UTC

Author: jason
Date: Fri Jun  1 21:19:22 2012
New Revision: 188127

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=188127
Log:
	PR c++/52725
	* parser.c (cp_parser_binary_expression): Bail early if we're parsing
	tentatively and the LHS has a parse error.

Added:
    trunk/gcc/testsuite/g++.dg/parse/new6.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/template/sizeof-template-argument.C


Comment 9


Jason Merrill



2012-06-01 21:19:42 UTC

Author: jason
Date: Fri Jun  1 21:19:36 2012
New Revision: 188128

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=188128
Log:
	PR c++/52725
	* parser.c (cp_parser_binary_expression): Bail early if we're parsing
	tentatively and the LHS has a parse error.

Added:
    branches/gcc-4_7-branch/gcc/testsuite/g++.dg/parse/new6.C
Modified:
    branches/gcc-4_7-branch/gcc/cp/ChangeLog
    branches/gcc-4_7-branch/gcc/cp/parser.c
    branches/gcc-4_7-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_7-branch/gcc/testsuite/g++.dg/template/sizeof-template-argument.C


Comment 10


Jason Merrill



2012-06-01 21:20:19 UTC

Fixed for 4.7.1.

  • Forum
  • Beginners
  • lazy initialisation with shared pointer

lazy initialisation with shared pointer

Hi

I am trying to introduce a lazy initialisation using a shared pointer.
The function that performs the initialisation is a public member function and uses a lambda.

I am unsure if the lambda is correct though. A compile error is generated on the code.

A small subset of the code looks something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <memory>
#include <string>
#include <mutex>

class Member;

using sharep = std::shared_ptr<Member>;

class Member {
  private:
    std::string sname;
    int sage{0};
    std::once_flag once_flag;

  public:
    Member(std::string & name, int age) :  sname{name}, sage{age}  { }
    Member() {}

    Member ( const Member & ) = delete; // avoid copy


    ~Member() {}
    void init_profile(const std::string & name, const int age) {
      sname = name;
    }

    const std::string view_profile() const {
      return "Name : " + sname + ", age: " + std::to_string(sage) ;
    }

    void init(sharep & sptr, const std::string & name, const int age ) {
      std::call_once(once_flag, [sharep & sptr](){ if(!sptr) sptr.reset(new Member); } )
      sptr->init_profile(name, age);
    }
};

int main() {
  sharep sptr;
  sptr.init(sptr, "Harry Potter", 12);
  std::cout << "Profile : " << sptr->view_profile() << "n";

  return 0;
}

The compile error is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
lazy_init_thread_safe02.cpp: In member function ‘void Member::init(sharep&, const string&, int)’:
lazy_init_thread_safe02.cpp:33:34: error: capture of non-variable ‘using sharep = class std::shared_ptr<Member>’
       std::call_once(once_flag, [sharep & sptr](){ if(!sptr) sptr.reset(new Member); } )
                                  ^~~~~~
lazy_init_thread_safe02.cpp:8:39: note: ‘using sharep = class std::shared_ptr<Member>’ declared here
 using sharep = std::shared_ptr<Member>;
                                       ^
lazy_init_thread_safe02.cpp:33:41: error: expected ‘,’ before ‘&’ token
       std::call_once(once_flag, [sharep & sptr](){ if(!sptr) sptr.reset(new Member); } )
                                         ^
lazy_init_thread_safe02.cpp:34:7: error: expected ‘;’ before ‘sptr’
       sptr->init_profile(name, age);
       ^~~~
lazy_init_thread_safe02.cpp: In function ‘int main()’:
lazy_init_thread_safe02.cpp:41:8: error: ‘using sharep = class std::shared_ptr<Member> {aka class std::shared_ptr<Member>}’ has no member named ‘init’
   sptr.init(sptr, "Harry Potter", 12);
        ^~~~
Compilation failed.

Could anybody suggest where the code needs modification ?

Last edited on

std::call_once(once_flag, [/*sharep*/ & sptr](){ if(!sptr) sptr.reset(new Member); } ) ; //missing semicolon http://en.cppreference.com/w/cpp/language/lambda (see lambda capture)

But then on line 40 you do
sptr->init(sptr, "Harry Potter", 12); //dereference the pointer
sptr is a null pointer at that time. don’t derefence null pointers.

Hi ne555
Thanks for the reply.

No compile error appears now, but
a runtime «segmentation fault» occurs instead, with the modified code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <memory>
#include <string>
#include <mutex>

class Member;
using sharep = std::shared_ptr<Member>;

class Member {
  private:
    std::string sname;
    int sage{0};
    std::once_flag once_flag; // std::once_flag cannot be copied or moved

  public:
    Member(const std::string & name, int age) :  sname{name}, sage{age}  { }
    Member() {}
    Member ( const Member & ) = delete; // avoid copy
    ~Member() {}

    void init_profile(const std::string & name, const int age) {
      sname = name;  sage = age;
    }

    const std::string view_profile() const {
      return "Name : " + sname + ", age: " + std::to_string(sage);
    }

    void init(sharep & sptr, const std::string & name, const int age ) {
      std::call_once(once_flag, [/*sharep*/ & sptr](){ if(!sptr) sptr.reset(new Member); } ) ;
      sptr->init_profile(name, age);
    }
};

int main() {
  sharep sptr;
  sptr->init(sptr, "Harry Potter", 12);
  std::cout << "Profile : " << sptr->view_profile() << "n";
  return 0;
}

Again,
sptr->init(sptr, "Harry Potter", 12);
Will cause UB because sptr is empty.

Last edited on

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <memory>
#include <string>
#include <mutex>

class Member;
using sharep = std::shared_ptr<Member>;

class Member {
  private:
    std::string sname;
    int sage{0};
    std::once_flag once_flag; // std::once_flag cannot be copied or moved

  public:
    Member(const std::string & name, int age) :  sname{name}, sage{age}  { }
    Member() {}
    Member ( const Member & ) = delete; // avoid copy
    ~Member() {}

    void init_profile(const std::string & name, const int age) {
      sname = name;  sage = age;
    }

    const std::string view_profile() const {
      return "Name : " + sname + ", age: " + std::to_string(sage);
    }

    void init(sharep & sptr, const std::string & name, const int age ) {
      std::call_once(once_flag, [/*sharep*/ & sptr](){ if(!sptr) sptr.reset(new Member); } ) ;
      sptr->init_profile(name, age);
    }
};

int main() {
	sharep sptr(new Member()); // you missed this line
	sptr->init(sptr, "Harry Potter", 12);
	std::cout << "Profile : " << sptr->view_profile() << "n";
	return 0;
}

Last edited on

Hi blongho,

many thanks. I’m only a beginner C++ coder, but slowly making my way through C++ Concurrency in Action by Anthony Williams.
The above code is simply a test case I’ve created in order to try out some of his discussion on pages 60-63.

one small change,

I modified line 36, from this:
sharep sptr(new Member());
to this:
sharep sptr = std::make_shared<Member>();

so no lazy initialization then.

Topic archived. No new replies allowed.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Error captcha is invalid перевод
  • Error cappsystemdict loadsystemanddependencies appsystemdict дота
  • Error cant send error report to the server
  • Error cant open log
  • Error cant open config

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии