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

У меня возникли проблемы с пониманием того, как расширение 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 напрямую или передавая его функции?

1 ответ

Применимое правило находится в §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(); следовательно, программа плохо сформирована. Чтобы использовать такую ​​функцию, определение должно быть видимым для компилятора.

Другие вопросы по тегам