Есть ли способ что-то утверждать об аргументе функции consteval с значимым сообщением об ошибке в случае сбоя?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Есть ли способ что-то утверждать об аргументе функции consteval с значимым сообщением об ошибке в случае сбоя?

Сообщение Anonymous »

Я хочу иметь (в C++20) константный конструктор, который принимает string_view в качестве аргумента и утверждает что-то о свойствах этого аргумента во время компиляции. Например:

Код: Выделить всё

#include 
#include 

constexpr bool IsValid(std::string_view foo) {
return foo.length() > 2;
}

struct Wrapper {
consteval Wrapper(const char* name) : name_(name) {
// Doesn't work because name is not an integral constant expression
static_assert(IsValid(name), "Must be valid");
}

std::string_view name_;
};

int main() {
// Should compile fine
Wrapper ok { "ABC" };
// Should fail to compile
Wrapper bad { "A" };

return 0;
}
Основываясь на этом и другом вопросе, я решил, что большую часть пути можно добиться, заменив static_assert блоком if, который содержит что-то, что не Компилирую. Например, конструктор может иметь вид:

Код: Выделить всё

consteval Wrapper(const char* name) : name_(name) {
if (!IsValid(name)) {
std::abort();
}
}
Который ведет себя так, как хотелось бы, и не работает с недопустимыми строками.
Тем не менее, сообщение об ошибке довольно плохо указывает, в чем заключается ошибка для пользователей этот API. В данном случае ошибка clang:

Код: Выделить всё

:23:13: error: call to consteval function 'Wrapper::Wrapper' is not a constant expression
23 |     Wrapper bad { "A" };
|             ^
:11:13: note: non-constexpr function 'abort' cannot be used in a constant expression
11 |             std::abort();
|             ^
:23:13: note: in call to 'Wrapper(&"A"[0])'
23 |     Wrapper bad { "A" };
Вместо этого я мог бы определить пустую функцию, не вычисляемую константой, с аргументом const char*, чтобы хотя бы получить a сообщение об ошибке . Что-то вроде:

Код: Выделить всё

void bad_name(const char*) {}

consteval Wrapper(const char* name) : name_(name) {
if (!IsValid(name)) {
bad_name("name passed to Wrapper is invalid");
}
}
Что не получается:

Код: Выделить всё

:25:13: error: call to consteval function 'Wrapper::Wrapper' is not a constant expression
25 |     Wrapper bad { "A" };
|             ^
:13:13: note: non-constexpr function 'bad_name' cannot be used in a constant expression
13 |             bad_name("The name supplied to Wrapper is invalid");
|             ^
:25:13: note: in call to 'Wrapper(&"A"[0])'
25 |     Wrapper bad { "A" };
Может быть, мне не хватает очевидного средства типа Assert() в языке C++ или стандартной библиотеке, которое можно было бы использовать в этом контексте? Если нет, есть ли что-нибудь в самом языке, что сделало бы непрактичным стандартизацию подобных вещей?

Подробнее здесь: https://stackoverflow.com/questions/792 ... unction-wi
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»