17

在下面的代码中,什么函数可以为外部使用提供最佳优化,为什么?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;
};

非常感谢你。

4

2 回答 2

22

我相信中的代码是<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;}

那么这个函数不能在编译时调用,因此不能在需要编译时常量的上下文中使用。如果您的应用程序或您的客户不需要此类功能,这可能不会对他们造成任何伤害。但是恕我直言,如果您有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的问题。

于 2012-08-12T01:56:00.700 回答
0

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

从编译器的角度来看,上面的代码与此没有什么不同:

static unsigned int size() { return 42; }

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

于 2012-08-12T01:52:59.287 回答