Шаблон шаблона C ++ не удалось скомпилировать - PullRequest
0 голосов
/ 15 сентября 2018

У меня есть эта тестовая программа

#include<iostream>
#include<vector>
using namespace std;

template<template<class> class C, typename T>
void print(const C<T>& c){
    for(auto& e : c)cout<<e<<endl;
}
int main(){
    vector<int> v;
    print(v);
    return 0;
}

Не удается скомпилировать:

g++ m.cpp -std=c++11
m.cpp: In function ‘int main()’:
m.cpp:11:16: error: no matching function for call to ‘print(std::vector<int>&)’
        print(v);
                ^
m.cpp:6:6: note: candidate: template<template<class> class C, class T> void print(const C<T>&)
void print(const C<T>& c){
    ^~~~~
m.cpp:6:6: note:   template argument deduction/substitution failed:
m.cpp:11:16: note:   template parameters of a template template argument are inconsistent with other deduced template arguments
        print(v);
                ^

Я изменил подпись print () с (const C & c) на (C & c), она все еще не работает:

$ g++ m.cpp -std=c++11
m.cpp: In function ‘int main()’:
m.cpp:11:16: error: no matching function for call to ‘print(std::vector<int>&)’
        print(v);
                ^
m.cpp:6:6: note: candidate: template<template<class> class C, class T> void print(C<T>&)
void print(C<T>& c){
    ^~~~~
m.cpp:6:6: note:   template argument deduction/substitution failed:
m.cpp:11:16: note:   template parameters of a template template argument are inconsistent with other deduced template arguments
        print(v);
                ^

Как это исправить?

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

std::vector содержит два параметра шаблона, в то время как параметр шаблона C объявлен как содержащий только один.В любом случае, ваш код будет хорошо работать с C ++ 17;начиная с C ++ 17 ( CWG 150 ), аргументы шаблона по умолчанию разрешены для аргумента шаблона шаблона , чтобы соответствовать параметру шаблона шаблона с меньшим количеством параметров шаблона.

LIVE

До C ++ 17 вы можете применить пакет параметров .

template<template<class...> class C, typename T>
void print(const C<T>& c){
    for(auto& e : c)cout<<e<<endl;
}

LIVE

0 голосов
/ 15 сентября 2018

Ваша проблема с компиляцией возникает из-за того, что ваш параметр шаблона шаблона C не соответствует объявлению std::vector:

template<
    class T,
    class Allocator = std::allocator<T>
> class vector;

Как вы можетесм., std::vector имеет два параметра шаблона, в то время как ваш C имеет только один. Но, обратите внимание также, что второй параметр (class Allocator) имеет аргумент типа default ,Начиная с C ++ 17, это правильно, даже так, как вы написали, так как было добавлено, что параметры шаблона шаблона соответствие не требует указания параметров для параметров с параметрами по умолчанию, такими как Allocator,Но не все компиляторы поддерживают эту модификацию языковой спецификации - смотрите здесь, как Clang 6.0.0 отказывается откомпилировать ваш оригинальный фрагмент с включенным C ++ 17.Что касается более старых версий C ++ (или любой другой версии на сегодняшний день Clang), этот фрагмент, вероятно, является тем, к чему вы стремились:

template<template<class, class> class C, typename T, typename A>
void print(const C<T, A>& c){
    for(auto& e : c)cout<<e<<endl;
}

Так как здесь вы указываете правильную сигнатуру шаблона типа (* 1025)*) вы позже создаете экземпляр print() с помощью.


Это также будет работать, независимо от C ++ 17:

template<template<class...> class C, typename T>
void print(const C<T>& c){
    for(auto& e : c)cout<<e<<endl;
}

Тем не менее, обратите внимание, что* * * * * * * *, поскольку vector<int> уже является полностью экземпляризованным типом, эта более простая версия работает так же хорошо в заданной области действия вашего фрагмента:

template<typename T>
void print(const T& c){
    for(auto& e : c)cout<<e<<endl;
}

Я изменилprint () подпись от (const C& c) до (C& c), она по-прежнему не работает:

Это, вероятно, лучшая практика в этом случае, поскольку вы не изменяете c внутри print(),Однако это не имеет отношения к вашей ошибке.

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