2015-02-27 3 views
1

Я пытаюсь написать обобщенную функцию набора мощности для контейнеров STL C++ с использованием аргумента шаблона шаблона. Проблема сводится к следующему аргументу шаблона дедукции/подмены неисправного:C++ функция с шаблоном шаблон аргумент fail шаблон аргумент вычет/подстановка

template <typename T, template<typename> class C> 
C<C<T>> getPowerSet(typename C<T>::iterator begin, typename C<T>::iterator end) 
... 
vector<vector<int>> powerSet = getPowerSet<int, vector>(set.begin(), set.end()); 

код и ошибка компилятора (с помощью г ++ (GCC) 4.8.1 20130531 (Red Hat 4.8.1-1)) следуют. Я прокомментировал части, не связанные с ошибкой компилятора.

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

template <typename T, template<typename> class C> 
C<C<T>> getPowerSet(typename C<T>::iterator begin, typename C<T>::iterator end) 
{ 
    C<C<T>> powerSet; 
    /* 
    if (begin == end) 
     return powerSet; 

    C<C<T>> subproblem = getPowerSet(begin + 1, end); 
    copy(subproblem.begin(), subproblem.end(), inserter(powerSet, powerSet.end())); 
    for (C<T> set : subproblem) 
    { 
     *inserter(set, set.begin()) = *begin; 
    } 
    copy(subproblem.begin(), subproblem.end(), inserter(powerSet, powerSet.end())); 
    */ 
    return powerSet; 
} 

int main() 
{ 
    vector<int> set; 
    for(int i = 0; i < 5; ++i) 
     set.push_back(i); 
    vector<vector<int>> powerSet = getPowerSet<int, vector>(set.begin(), set.end()); 
    /* 
    for (auto set : powerSet) 
    { 
     for (int elem : set) 
     { 
      cout << elem << " "; 
     } 
     cout << endl; 
    } 
    */ 
} 

Ниже ошибка компилятора:

[[email protected] recursion]$ g++ 3.cpp 
3.cpp:8:15: error: template argument 1 is invalid 
C<typename C<T>> getPowerSet(typename C<T>::iterator begin, typename C<T>::iterator end) 
      ^
3.cpp: In function ‘int main()’: 
3.cpp:31:83: error: no matching function for call to ‘getPowerSet(std::vector<int>::iterator, std::vector<int>::iterator)’ 
    vector<vector<int>> powerSet = getPowerSet<int, vector>(set.begin(), set.end()); 
                       ^
3.cpp:31:83: note: candidate is: 
3.cpp:8:18: note: template<class T, template<class> class C> int getPowerSet(typename C<T>::iterator, typename C<T>::iterator) 
C<typename C<T>> getPowerSet(typename C<T>::iterator begin, typename C<T>::iterator end) 
       ^
3.cpp:8:18: note: template argument deduction/substitution failed: 
+0

@Praetorian Обратите внимание, что C и T явно указаны в вызове функции. – jrok

+0

@jrok Да, не внимательно прочитал вопрос, только посмотрел на подпись функции – Praetorian

+0

[This] (http://stackoverflow.com/a/16925220/1277769) может ответить на ваш вопрос. – SirGuy

ответ

1

Если изменить подпись принять аргумент шаблона с переменным списком параметров

template <typename T, template<typename...> class C> 
//        ^^^^^^^^^^^ 
C<C<T>> getPowerSet(typename C<T>::iterator begin, typename C<T>::iterator end) 

вам больше не нужно добавлять тип распределителя к вызову.

+0

omg, это так сложно и потрясающе. – user804649

1

друга по электронной почте мне следующий камень (тьфу ты по умолчанию аргумент шаблона):

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

template <typename T, typename S, template<typename, typename> class C> 
C<C<T, S>, std::allocator<C<T, S> > > getPowerSet(typename C<T, S>::iterator begin, typename C<T, S>::iterator end) 
{ 
    C<C<T, S>, std::allocator<C<T, S> > > powerSet; 
    /* 
    if (begin == end) 
     return powerSet; 

    C<C<T>> subproblem = getPowerSet(begin + 1, end); 
    copy(subproblem.begin(), subproblem.end(), inserter(powerSet, powerSet.end())); 
    for (C<T> set : subproblem) 
    { 
     *inserter(set, set.begin()) = *begin; 
    } 
    copy(subproblem.begin(), subproblem.end(), inserter(powerSet, powerSet.end())); 
    */ 
    return powerSet; 
} 

int main() 
{ 
    vector<int> set; 
    for(int i = 0; i < 5; ++i) 
     set.push_back(i); 
    auto powerSet = getPowerSet<int, std::allocator<int>, vector>(set.begin(), set.end()); 
    /* 
    for (auto set : powerSet) 
    { 
     for (int elem : set) 
     { 
      cout << elem << " "; 
     } 
     cout << endl; 
    } 
    */ 
}