对于静态const getter,内联vs constexpr?

时间:2012-08-12 00:37:56

标签: c++ c++11 inline constexpr

在下面的代码中,哪个函数可以为外部使用提供最佳优化,为什么? C ++ 2011中是否允许“版本4”?

template<unsigned int TDIM> class MyClass 
{
    public:
        static inline unsigned int size()           {return _size;} // Version 1
        static inline const unsigned int size()     {return _size;} // Version 2
        static constexpr unsigned int size()        {return _size;} // Version 3
        static inline constexpr unsigned int size() {return _size;} // Version 4
    protected:
        static const unsigned int _size = TDIM*3;
};

非常感谢。

2 个答案:

答案 0 :(得分:21)

我相信<random>中的代码树立了一个很好的榜样,但也不需要盲目跟随。在<random>中,您会看到以下两种风格:

template<unsigned int TDIM> class MyClass 
{
    public:
        static constexpr unsigned int size() {return _size;}  // 1
        static constexpr unsigned int dim = TDIM;             // 2
    private:
        static const unsigned int _size = TDIM*3;
};

1和2之间的选择主要是风格。当它们以需要编译时结果的方式使用时,它们在编译时都被解析。您希望您的客户输入()吗?是否需要使用一种风格或另一种风格的通用代码?满足通用代码的要求是关键。

使用inline关键字对此没有影响。我认为它过于冗长,但如果你使用它,它没有任何伤害并且没有任何影响。

const添加到返回类型不会对此产生任何影响。我认为它过于冗长,但如果你使用它,它没有任何伤害并且没有任何影响。

如果使用功能样式,但不要使用constexpr

    static unsigned int size() {return _size;}

然后在编译时不能调用此函数,因此不能在需要编译时常量的上下文中使用。如果您的应用程序或客户不需要此类功能,则不会对您造成任何伤害。但是imho,如果你在工具箱中有constexpr,这是使用它的最佳位置。如果你做未来的客户可以做这样的事情:

template <unsigned N> struct B {};
constexpr auto myclass = MyClass<3>();
// ...
// lots of code here
// ...
B<myclass.size()> b;

这两个是等价的:

        static constexpr unsigned int dim = TDIM;        // 2
        static const unsigned int dim = TDIM;            // 3

但仅仅因为涉及的类型是不可或缺的。如果类型不是整数,则必须使用constexpr,类型必须有constexpr构造函数:

class A
{
    unsigned _i;
public:
    constexpr A(unsigned i) : _i(i) {}
};

template<unsigned int TDIM> class MyClass 
{
    public:
        static constexpr unsigned int size() {return _size;}
        static constexpr unsigned int dim = TDIM;
        static constexpr A a = A(dim);
    private:
        static const unsigned int _size = TDIM*3;
};

此处的所有人,包括我自己,仍在学习如何使用constexpr。所以在问题上+1。

答案 1 :(得分:0)

静态const整数值被视为常量而不是编译器的变量。根据常数,它们可能根本不会占用任何内存。在所有示例中,函数将返回一个常量值,并且几乎总是内联(如上所述,在此示例中不需要inline关键字,因为所有声明都已内联)。

上面的代码与编译器的角度没有区别:

static unsigned int size() { return 42; }

版本2中的'const'关键字也不是必需的。我相信只有返回指针或引用才有意义。