C++常量结构体成员初始化

11

我在我的类中有一个不变的struct timespec成员变量。我该如何初始化它?

我唯一疯狂的想法是派生出自己的timespec并给它提供一个构造函数。

非常感谢!

#include <iostream>

class Foo
{
    private:
        const timespec bar;

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

        }
};


int main() {
    Foo foo;    
    return 0;
}
编译出现错误:source.cpp: 在构造函数 'Foo::Foo()' 中:source.cpp:9:36: 错误:没有找到与 'timespec::timespec(int, int)' 匹配的函数 source.cpp:9:36: 提示:候选函数有: 在文件包含 sched.h:34:0 后, 从 pthread.h:25, 从 /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/i686-pc-linux-gnu/bits/gthr-default.h:41, 从 /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/i686-pc-linux-gnu/bits/gthr.h:150, 从 /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ext/atomicity.h:34, 从 /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/ios_base.h:41, 从 /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ios:43, 从 /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ostream:40, 从 /usr/lib/gcc/i686-pc-linux-gnu/4.7.2/../../../../include/c++/4.7.2/iostream:40, 从 source.cpp:1: time.h:120:8: 注意: timespec::timespec() time.h:120:8: 候选函数需要0个参数,但提供了2个 time.h:120:8: 注意: constexpr timespec::timespec(const timespec&) time.h:120:8: 候选函数需要1个参数,但提供了2个 time.h:120:8: 注意: constexpr timespec::timespec(timespec&&) time.h:120:8: 候选函数需要1个参数,但提供了2个

1
你尝试过只是初始化它吗? - Some programmer dude
当然,我做了。但是我收到了一个错误。我编辑了问题。 - Kolyunya
我不知道大家为什么要给我点踩,但我只是找不到正确的语法... - Kolyunya
我的意思是尝试像这样使用 const timespec bar = { 0, 0 }; - Some programmer dude
3个回答

13

在C++11中,你可以在构造函数的初始化器列表中初始化一个聚合成员:

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

在较早的版本中,你需要一个工厂函数:

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

static timespec make_bar() {timespec bar = {1,1}; return bar;}

Mike,请问你能否告诉我或提供一个好的链接,让我了解如何使用这个语法。因为 bar{1,1} {}bar{1,1}bar({1,1}) 都可以正常工作。那么正确的语法是什么? - Kolyunya
2
@Kolyunya:bar{1,1}bar({1,1})都是正确的;第一个指定了列表初始化,而第二个指定了从初始化器列表进行直接初始化,这两者都会做同样的事情。我会使用第一个,因为它更简洁明了,可以更清楚地表达我的意图。 - Mike Seymour

4

使用帮助函数和初始化列表:

#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;
}

1
我会将其作为一个static(内部链接)函数或者在C++11中甚至是一个lambda表达式,以避免污染类接口。 - David Rodríguez - dribeas
@DavidRodríguez-dribeas - 好想法。如果我考虑到了,我会将其制作为私有成员函数。只有在初始化通常与类功能无关时,才会将其制作为“static”自由函数。 - Robᵩ

3

使用初始化列表

class Foo
{
    private:
        const timespec bar;

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

        }
};

如果您想使用花括号初始化结构体,请确保使用它们。
Foo ( void ) : bar({1, 2})

值得注意的是,花括号初始化器是C++11的一个特性。 - Robᵩ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接