Вывод аргумента шаблона для initializer_list с пересылкой - PullRequest
0 голосов
/ 21 февраля 2019

Я хочу использовать перф.переадресация с помощью initializer_list (фигурные скобки), но мне не удалось написать код, который можно скомпилировать.

Как сделать так, чтобы вывод типов работал в следующем примере кода?

#include <utility>

template <class _T> struct B {
    _T a;
    _T b; };

template <class _T> void bar(B<_T>&& a) {}

template <class _T> void bar(B<_T>& a) {}

template <class _T> struct A {
    template <class __T>
    void foo(__T&& a) {
        bar(std::forward<__T>(a));
    } };

int main() {
    A<int> a;
    a.foo({1, 3}); }

Iзнаю, что можно сделать идеальную пересылку с аргументом шаблона variadic, например:

#include <utility>

template <class _T>
struct B {
    _T a;
    _T b;
};

template <class _T>
void bar(_T&& v1, _T&& v2) {
    B<_T> b{v1, v2};
}

template <class _T>
void bar(_T& v1, _T& v2) {
    B<_T> b{v1, v2};
}

template <class _T>
struct A {
    template <class... Args>
    void foo(Args&&... args) {
        bar(std::forward<Args>(args)...);
    }
};

int main() {
    A<int> a;
    a.foo(1, 3);
}

Но я хочу позвонить foo с милыми фигурными скобками.

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

{1, 3} не имеет типа, поэтому не может быть выведен для "универсального" типа шаблона.

Вы можете использовать перегрузку с std::initializer_list для обработки;

template <class T>
struct A {
    template <class U>
    void foo(U&& a) {
        bar(std::forward<U>(a));
    }

    template <class U>
    void foo(std::initializer_list<U> a) {
        bar(a); // assuming bar(std::initializer_list<U>)
    }

};

int main() {
    A<int> a;
    a.foo({1, 3});
}
0 голосов
/ 21 февраля 2019

Вы не можете.Наряду с другими серьезными недостатками, std::initializer_list не может быть выведен простым использованием синтаксиса {...}.

a.foo(std::initializer_list{1, 3})

Будет правильно проходить удержание, но вы не сможете вызвать bar с ним каквы ожидаете экземпляр B.

живой пример на wandbox.org


Как насчет просто

a.foo(B<int>{1, 3})

?

...