Почему это неоднозначный вызов функции с использованием GCC? Шаблонный вывод не удался?

Я знаю, что я хочу, чтобы они делали, мне все равно, как они это делают: Интерфейс.

Я знаю, что я хочу, чтобы они делали, мне все равно, как они делают некоторые из это, но у меня есть твердые идеи о том, как они (или, по крайней мере, большинство из них) выполняют другие биты: абстрактный класс.

Я знаю, что я хочу, чтобы они делали, и как большинство из них сделайте это: Конкретный класс с виртуальными членами.

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

(Кстати, я бы не подумал о Петре как о человеке, а о каждом пэтере как о человеке, которого, как говорят, называют Питером. код таким образом, но когда вы думаете об этой проблеме, это более уместно, чем обычно).

3
задан pjgeorg 18 January 2019 в 12:35
поделиться

1 ответ

  • Позвольте упростить задачу для gcc:

    template<class... Ts, int... Ns>
    void error(Base<Ts, Ns...> const &... args) {} // #1
    
    template<class... Ts,
        std::enable_if_t<
            std::conjunction<std::is_class<std::remove_reference_t<Ts>>...>{}, int> = 0>
    void error(Ts &&... args) {} #2
    
    int main()
    {
        const Base<int, 4> b;
    
        error(b); // call #1
    }
    

    Следуя (сложным) правилам overload_resolution

    , у нас есть оба метода в качестве жизнеспособных функций обе являются шаблонными, поэтому мы используем более специализированный шаблон

    Я (как clang) понимаю, что # 1 более специализирован, чем # 2, но не для gcc

    Демо

    Я бы сказал, gcc bug.

  • Позвольте упростить задачу для clang:

    template<class... Ts, int... Ns>
    void error(Base<Ts, Ns...> const &... args) {} // #1
    
    template<class... Ts,
        std::enable_if_t<
            (... && std::is_class<std::remove_reference_t<Ts>>::value), int> = 0>
    void error(Ts&&... args) {} // #2
    
    int main()
    {
        Derived<int, 4, 4> d;
        error(d); // call #2
    }
    

    ICE всегда ошибка, так что ошибка clang.

    Для разрешения # 2 является точным соответствием, тогда как # 1 требует преобразования производного класса в его базу.

    gcc соглашается с тем, что # 2 называется.

    Демо

0
ответ дан Jarod42 18 January 2019 в 12:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: