在下面的代码中,哪个函数可以为外部使用提供最佳优化,为什么? 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;
};
非常感谢。
答案 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'关键字也不是必需的。我相信只有返回指针或引用才有意义。