Можно ли создать экземпляр std:: reference_wrapper <T>, где T - неполный тип?
Разрешает ли std::reference_wrapper<T>
T
быть неполным, так же, как a T&
можно обрабатывать без завершения T
?
GCC 4.9 принимает следующее:
#include <functional>
struct woof;
struct test
{
test(woof& w) : w(w) {}
std::reference_wrapper<woof> w;
};
struct woof
{
int a;
};
int main()
{
woof w;
test t = w; // (braced-init would be better, but VS2012!)
}
Но MSVS 2012 отклоняет его со следующим сообщением:
Ошибка 1 ошибка C2139: 'woof': класс undefined не разрешен в качестве аргумента для атрибута встроенного типа компилятора '__is_abstract' c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits 755 1 тест3
Я подозреваю, что это потому, что op()
нужен полный тип, но стандарт не указывает на какой-либо способ.
Что, если любая из этих реализаций соответствует стандартным мандатам?
Ответы
Ответ 1
N3936 § 17.6.4.8 Другие функции [res.on.functions]:
1 В некоторых случаях (функции замены, функции обработчика, операции с типами, используемыми для создания стандартных компонентов шаблона библиотеки) стандартная библиотека С++ зависит от компонентов, предоставляемых программой на С++. Если эти компоненты не соответствуют их требованиям, Стандарт не устанавливает никаких требований к реализации.
2 В частности, эффекты undefined в следующих случаях:
- ...
- если неполный тип (3.9) используется в качестве аргумента шаблона при создании экземпляра компонента шаблона, если специально не разрешено для этого компонента.
Быстрое сканирование через 20.9.3 Шаблон класса reference_wrapper
[refwrap] не показывает такого конкретного исключения для reference_wrapper
, поэтому ваша программа имеет поведение undefined. Обе реализации соответствуют.