Использование constexpr для проверки литеральных параметров в конструкторе

Я начал экспериментировать с constexpr,
То, что я пытаюсь достичь, это проверить literal числовые значения
предоставляется в качестве параметров ctor.
Я начал со следующего, бросая, если строит MyStruct
со значением <= 4

constexpr int validate(int v)
{
return (v > 4) ? v : throw exception();
};

struct MyStruct final
{
constexpr MyStruct(const int v)
: _v{validate(v)}
{
}

void add(int toAdd)
{
_v += toAdd;
}

int _v;
};

int main(int argc, char**)
{
constexpr MyStruct a{500};  // ok so far...
a.add(argc);                // ...nope
MyStruct b{500};            // check at runtime :(
MyStruct c{argc};           // runtime check ok
}

маркировка MyStruct как constexpr работает как положено, но это предотвращает вызов add так как это не изменчиво.

Я думаю, что это можно сделать, поскольку я нацеливаюсь только на буквальные значения (известные во время компиляции).
Я хотел бы избежать шаблонов.

3

Решение

Аргументы функции не являются константным выражением: — /

Вы могли бы пройти std::integral_constant<std::size_t, 4u> чтобы разрешить проверку времени компиляции внутри конструктора:

struct MyStruct final
{
// For runtime or constexpr usage.
constexpr MyStruct(int v) : _v{validate(v)} {}

// For compile-time values
template <std::size_t N>
constexpr MyStruct(std::integral_constant<std::size_t, N>) : _v{N}
{
static_assert(N > 4, "Unexpected");
}

// ...
};

а потом

MyStruct b{std::integral_constant<std::size_t, 500>{}};
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]