Ответ 1
Я считаю, что код в <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 на вопрос.