Использование функций, которые возвращают типы заполнителей, определенные в другом модуле перевода

У меня возникли проблемы с пониманием того, как расширение C ++ 14 auto спецификатор типа, описанный в N3638 может быть реализовано, и что, собственно, разрешено.

В частности, одно из изменений в стандарте гласит:

Если объявленный тип возврата функции содержит тип заполнителя, тип возврата функции выводится из операторов возврата в теле функции, если таковые имеются.

Достаточно легко увидеть, как это работает, когда тело функции находится в том же файле, что и объявление; но рассмотрим случай, когда заголовочный файл объявляет метод, использующий auto заполнитель, но не определяет Это. Как переводить блоки, которые включают этот заголовочный файл, но делают не включить файл, который определяет метод, будет успешно скомпилирован?

Например, учитывая файл foo.hpp:

class foo
{
public:
auto gen_data();
};

…и файл foo.cpp:

struct data_struct
{
int a;
int b;
int c;
double x;
char data[37];
};

auto foo::gen_data()
{
data_struct d;
// initialize members in d...
return d;
}

…и файл main.cpp:

#include "foo.hpp"
template<typename T>
double get_x(T f)
{
return f.gen_data().x;
}

int make_and_get_x()
{
foo f;
return get_x<foo>(f);
}

…законно ли компилировать main.cpp сам по себе? Если нет, то почему нет? Если так, то как get_x экземпляр, так как компилятор не может знать, является ли возвращаемый тип gen_data даже есть член по имени xне говоря уже о его смещении?

Похоже, что это будет проблемой, даже не беспокоясь о реализации шаблона; например, что произойдет, если вы попытаетесь получить доступ f.gen_data().x напрямую или передавая его функции?

3

Решение

Применимое правило находится в §7.1.6.4 [dcl.spec.auto] / p11:

Если требуется тип сущности с неопределенным типом заполнителя
чтобы определить тип выражения, программа плохо сформирована.

Есть пример:

auto f();
void g() { &f; }  // error, f’s return type is unknown

Вам нужен тип gen_data определить тип выражения x.gen_data(); следовательно, программа плохо сформирована. Чтобы использовать такую ​​функцию, определение должно быть видимым для компилятора.

2

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


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