11

I've a constant struct timespec member in my class. How am I supposed to initialize it?

The only crazy idea I got is to derive my own timespec and give it a constructor.

Thanks much!

#include <iostream>

class Foo
{
    private:
        const timespec bar;

    public:
        Foo ( void ) : bar ( 1 , 1 )
        {

        }
};


int main() {
    Foo foo;    
    return 0;
}

Compilation finished with errors: source.cpp: In constructor 'Foo::Foo()': source.cpp:9:36: error: no matching function for call to 'timespec::timespec(int, int)' source.cpp:9:36: note: candidates are: In file included from sched.h:34:0, from pthread.h:25, from /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/i686-pc-linux-gnu/bits/gthr-default.h:41, from /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/i686-pc-linux-gnu/bits/gthr.h:150, from /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ext/atomicity.h:34, from /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/ios_base.h:41, from /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ios:43, from /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ostream:40, from /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/iostream:40, from source.cpp:1: time.h:120:8: note: timespec::timespec() time.h:120:8: note: candidate expects 0 arguments, 2 provided time.h:120:8: note: constexpr timespec::timespec(const timespec&) time.h:120:8: note: candidate expects 1 argument, 2 provided time.h:120:8: note: constexpr timespec::timespec(timespec&&) time.h:120:8: note: candidate expects 1 argument, 2 provided

Kolyunya
  • 5,973
  • 7
  • 46
  • 81

3 Answers3

13

In C++11, you can initalise an aggregate member in the constructor's initialiser list:

Foo() : bar{1,1} {}

In older versions of the language, you would need a factory function:

Foo() : bar(make_bar()) {}

static timespec make_bar() {timespec bar = {1,1}; return bar;}
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Mike, could you please tell me or throw a good link about how do I use this syntax. Since `bar{1,1} {}`, `bar{1,1}` and `bar({1,1})` work correctly. What is the correct syntax? – Kolyunya Sep 28 '12 at 14:22
  • 2
    @Kolyunya: `bar{1,1}` and `bar({1,1})` are both correct; the first specifies list-initialisation, while the second specifies direct-initialisation from an initialiser list, which does the same thing. I'd use the first because it's less squiggly, and says more clearly what I want to do. – Mike Seymour Sep 28 '12 at 14:40
4

Use an initialization list with a helper function:

#include <iostream>
#include <time.h>
#include <stdexcept>

class Foo
{
    private:
        const timespec bar;

    public:
        Foo ( void ) : bar ( build_a_timespec() )
        {

        }
    timespec build_a_timespec() {
      timespec t;

      if(clock_gettime(CLOCK_REALTIME, &t)) {
        throw std::runtime_error("clock_gettime");
      }
      return t;
    }
};


int main() {
    Foo foo;    
    return 0;
}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • 1
    I would make that a `static` (internal linkage) function or even a lambda in C++11 to avoid polluting the class interface. – David Rodríguez - dribeas Sep 28 '12 at 14:12
  • @DavidRodríguez-dribeas - Good thought. I'd have made it a private member function if I had been thinking about it. I'd make it a `static` free function only if the initialization is generally unrelated to the class functionality. – Robᵩ Sep 28 '12 at 14:20
3

Use initialization list

class Foo
{
    private:
        const timespec bar;

    public:
        Foo ( void ) :
            bar(100)
        { 

        }
};

If you want to initialize structure with bracers then use them

Foo ( void ) : bar({1, 2})
Denis Ermolin
  • 5,530
  • 6
  • 27
  • 44