Для чего нам нужен std :: as_const ()?

C ++ 11 дал нам std::add_const; с C ++ 17 у нас есть новая структура — std::as_const(). Бывший просто привязывает const перед типом, который вы предоставляете. Второй — это правильная (шаблон a) функция, а не trait типа, которая, кажется, делает то же самое — за исключением случая, когда тип является rvalue-ссылкой, и в этом случае его нельзя использовать.

Я не совсем понимаю мотивацию для предоставления std::as_const(), Зачем нам это нужно в дополнение к std::add_const?

16

Решение

«Потребность» — это сильное слово … std::as_const существует, потому что это полезно, а не строго необходимо. Так как это функция, а не черта, мы можем использовать ее, чтобы «добавить const» к фактическому ценности а не типы.

Более конкретно: предположим, у меня есть некоторая переменная my_value и я хочу рассматривать это как const, но не копируйте его. До C ++ 17 мне нужно было бы написать:

static_cast<const MyType&>(my_value)

и если я не хочу указывать тип явно, это будет:

static_cast<std::add_const_t<std::remove_reference_t<decltype(my_value)>> &>(my_value)

или, если вы хотите получить грязную работу и использовать кастинг в стиле C:

(const decltype(my_value) &) (my_value)

все это раздражает и многословно.

Вместо этого с C ++ 17 сейчас пишут std::as_const(my_value) и это все, что нужно сделать.

Заметки:

  • Эта функция отключена для ссылок rvalue, даже если она прекрасно работает для них. Причина в том, чтобы помочь вам избежать непреднамеренного сохранения ссылки на временное прошлое его уничтожения. Как объясняет @NicolBolas, если вы напишите что-то вроде:

    for(auto &x : std::as_const(returns_container())) { /* do stuff with x */ }
    

    затем время жизни возвращаемого контейнера заканчивается до первой итерации цикла. Очень легко пропустить!

  • За дополнительной (?) Информацией обращайтесь к официальному предложению этой функции полезности: P007R1, Адам Дэвид Алан Мартин и Алисдейр Мередит.

19

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

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

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