2015-10-07 2 views
30

Когда лямбда гарантирована быть тривиальной, если вообще когда-либо?Когда лямбда тривиальна?

Я предполагал, что если он захватывает только тривиальные типы или ничего, это будет тривиально. Тем не менее, у меня нет никаких стандартов.

Мотивация заключалась в перемещении некоторого кода с Visual C++ 12-14 и обнаружении каких-то статических утверждений не удалось при работе с лямбдами, которые я считал тривиальными.

Пример:

#include <type_traits> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    auto lambda = [](){}; 

    cout << boolalpha << is_trivially_copyable<decltype(lambda)>{} << endl; 
} 

Это производит false на vs140 но true в vs120 и звоном. Я не смог проверить gcc из-за отсутствия gcc> = 5. Я ожидаю, что это регресс в vs140, но я не уверен в правильном поведении здесь.

+4

gcc 5.2 производит также 'истинные': [Demo] (http://coliru.stacked-crooked.com/a/a7dc4ee4e32fb70a) – Jarod42

ответ

30

В стандарте не указывается, является ли тип замыкания (тип выражения лямбда) тривиальным или нет. Он явно оставляет это до реализации, что делает его не переносным. Боюсь, вы не можете положиться на ваш static_assert, производя что-нибудь согласованное.

Цитирование C++ 14 (N4140) 5.1.2/3:

... Реализация может определить тип закрытия по-разному от того, что описано ниже, если это не изменяет наблюдаемую поведение программа иначе, чем изменение:

  • размера и/или выравнивание типа закрытия,
  • является ли тривиальным копируемым типом закрытия (пункт 9),
  • ли тип закрытия является стандартным классом макета (раздел 9) или
  • ли тип закрытия является классом POD (раздел 9).

...

(выделено мной)

После разбора двойного отрицания в этом предложении, мы можем видеть, что реализация позволила решить, является ли тривиальным копируемыми тип закрытия, стандартная компоновка или POD.

+0

Ну, это очень грустно для меня :(Я не ожидал этого ответа вообще Думаю, я выучил урок о том, чтобы не делать предположений. – tahsmith

13

Согласно проекту стандарта N45275.1.2/3 лямбда-выражения [expr.prim.lambda] (курсив мой):

тип лямбда-выражения (который также является тип объекта замыкания ) является уникальным неназванным классом типа ununion, называемым типом замыкания , свойства которого описаны ниже. Этот тип класса не является ни агрегатом (8.5.1), ни буквальным типом (3.9). Тип замыкания объявляется в малой области видимости блока, области видимости класса или области пространства имен, которая содержит соответствующее лямбда-выражение. [ Примечание: Это определяет набор пространств имен и классов, связанных с с типом замыкания (3.4.2).Типы параметров модуля lambdadeclarator не влияют на эти связанные пространства имен и классы . - конец примечание] Реализация может определить тип закрытия отличается от того, что описано ниже, если это не изменяет наблюдаемое поведение программы иначе, чем изменение:

(3,1) - размер и/или выравнивание типа закрытия,

(3,2) - является ли тривиальным копируемыми типа закрытия (пункт 9),

(3,3) - The типа закрытия, является ли это класс стандартного макета (пункт 9), или

(3.4) - Тип закрытия - класс POD (раздел 9).

Реализация должна не добавить членов RValue ссылочного типа к типу запорного

Таким образом, это зависит от реализации.

Смежные вопросы