(Обратная) пересылка конструктора с идеальной пересылкойC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 (Обратная) пересылка конструктора с идеальной пересылкой

Сообщение Anonymous »

Предположим, у меня есть класс с конструктором consteval, который обеспечивает допустимое значение во время компиляции. (Существует также фабричный метод std::expected-returning, который проверяет свой аргумент во время выполнения, но для данного вопроса это не имеет значения.)

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

class ConstevalConstructible {
public:
consteval ConstevalConstructible(int value) : value_(value) {
// Validate value and fail compile if invalid.
}
// Copyable, movable, et cetera
private:
int value_;
}
Теперь предположим, что у меня есть общая структура-оболочка, которая может содержать любое значение:

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

template 
struct Wrapper {
template 
constexpr Wrapper(Args&&... args) : inner(std::forward(args)...) {}

T inner;
};
Поскольку constexpr позволяет вызывать конструктор в константном контексте, оболочка отлично работает как для создания во время выполнения, так и для создания constexpr:

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

// Fine
Wrapper foo{runtime_value};
// Also fine: Wrapper's constexpr constructor is evaluated at compile
// time and thus the ConstexprConstructible's constructor is too.
constexpr Wrapper bar{42};
Проблема возникает при использовании ConstevalConstructible с Wrapper:

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

// Fails to compile: the constexpr Wrapper constructor is not an
// immediate function, so it cannot invoke ConstevalConstructible's
// constructor using arguments that are not (within its body)
// constexpr.
Wrapper foo{5};
// Doesn't fix the problem from the compiler's point of view.
constinit Wrapper foo{5};
// This does work as long as ConstevalConstructible is movable or
// copyable, but gets annoying.
Wrapper bar{ConstevalConstructible{5}};
Проблема в том, что, хотя оценка constexpr распространяется наружу (constexpr в объявлении переменной приводит к тому, что конструктор Wrapper становится оценивается во время компиляции, что, в свою очередь, приводит к тому, что конструктор ConstexprConstructible оценивается во время компиляции), константность конструктора вместо этого должна будет распространяться изнутри наружу (

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

ConstevalConstructibleКонструктор 
, являющийся константным, должен был бы привести к тому, что конструктор Wrapper также был бы константным, поэтому вся конструкция Wrapper будет немедленно оценена). p>
Это похоже на то, как работает noException, где возможность выдачи метода может быть указана в терминах содержащегося типа. Однако мне неизвестен аналогичный способ сделать конструктор или функцию условно константными. Я подумывал о добавлении перегрузки consteval, но не знаю, как ее ограничить:

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

template 
struct Wrapper {
template 
constexpr Wrapper(Args&&... args) : inner(std::forward(args)...) {}
template 
consteval Wrapper(Args&&... args)
requires requires { /** What would I put here? **/ }
: inner(std::forward(args)...) {}

T inner;
};
Решаема ли эта проблема на C++20? Если нет, планируется ли добавить эту возможность в будущую версию?

Подробнее здесь: https://stackoverflow.com/questions/790 ... forwarding
Ответить

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

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

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

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

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