Вывод типа параметров шаблона функции - PullRequest
2 голосов
/ 14 марта 2011

У меня есть несколько вопросов, касающихся шаблонов функций.

Мой план состоял в том, чтобы создать оболочку, которая является производной от определенного пользователем класса и не только экспортирует публичные функции этого класса, но и его конструкторы. Поэтому я решил, что буду использовать несколько шаблонов конструктора (которые, я полагаю, работают точно аналогично шаблонам функций) с параметрами от 1 до n для удовлетворения большинства потребностей конструкторов.

Они бы просто вызывали конструктор и потом делали что-то еще, например это:

template <class T>
class Wrapper : public T
{
    public:
        template <class U>
        Wrapper(U &u) : T(u) { doSomething(); }

        template <class U, class V>
        Wrapper(U &u, V &v) : T(u,v) { doSomething(); }

        ...
};

Мое намерение состоит в том, чтобы зарегистрировать экземпляр в Wrapper-Ctor где-нибудь еще, и, с этого момента он может принимать вызовы виртуальных функций, определенных в T.

Мне пришлось использовать оператор ссылки в приведенном выше коде, чтобы гарантировать, что мой Wrapper-Ctor не имеет побочных эффектов на параметры, которые были переданы (Копия-строительство).

К моему удивлению, это всегда работало, за исключением временных, что является причиной, почему Я запутался в типах, которые выводятся компилятором в этой ситуации. Чтобы упростить ситуацию, я попытался сделать что-то похожее с помощью функции шаблона:

template <class T>
void foo(T &t)
{
    int x = ""; // intentional error
}

Вызов функции следующим образом:

std::string a; 
std::string &b = a;
foo(b);

К моему удивлению, компилятор отмечает [T = std :: string] в своем сообщении об ошибке. Я ожидал, что это будет [T = std :: string &], что вызвало бы передача ссылки на ссылку, что недопустимо.

Итак, почему компилятор выводит тип значения в этой ситуации? Возможно ли даже создать Wrapper-Ctor, который делает то, что я хочу, не Есть побочные эффекты на параметры, а также принимает временные эффекты?

Большое спасибо!

Ответы [ 4 ]

2 голосов
/ 14 марта 2011

Похоже, что спецификация C ++ явно заявляет, что это предполагаемое поведение.В частности, если у вас есть шаблонная функция, которая принимает параметр P, который зависит от аргумента типа шаблона, если P является ссылкой, то для определения используется базовый тип ссылки, а не ссылочный тип.какой тип следует использовать для P (см. §14.8.2.1 / 2).Более того, в этом же разделе говорится, что квалификаторы const и volatile игнорируются на этом этапе, поэтому const может быть выведен автоматически.

1 голос
/ 17 июня 2011

Несколько поздно, но так как я не думаю, что на этот вопрос ответили полностью ...

Относительно вывода параметров шаблона см. Предыдущие ответы.

Для вашей проблемы с временными переменными сделайтепараметры const ссылки (как в Wrapper (const U &)).

Дело в том, что временные значения - это ценности.Стандарт гласит, что неконстантные ссылки могут быть связаны только с lvalues.Поэтому совместимый со стандартами компилятор не позволит вам передавать временные значения (rvalues) в качестве аргументов неконстантных ссылочных параметров.(Это не имеет ничего общего с шаблонами, в частности, это общее правило).

Насколько мне известно, так что отнеситесь к этому с небольшим скептицизмом.

1 голос
/ 15 марта 2011

Выражение не имеет ссылочного типа. Поэтому, когда вывод аргумента выводит тип выражения аргумента, он не может провести различие между a и b, поскольку аргументы a и b имеют одинаковый тип.

См. [Expr] p5 в спецификации

Если выражение изначально имеет тип «ссылка на T» (8.3.2, 8.5.3), тип корректируется до T перед любым дальнейшим анализом.

1 голос
/ 14 марта 2011

В C ++ 03 невозможно обеспечить такую ​​вещь без ручной перегрузки для каждой комбинации параметров const и non-const.

...