2013-03-21 16 views
15

mam błąd kompilacji przy użyciu std :: funkcji w matrycy funkcji składowej, następujący kod jest prosty przykład:szablon argumentu odliczenie/substytucja nie powiodła się, gdy za pomocą std :: funkcję i std :: wiążą

#include <functional> 
#include <memory> 
using std::function; 
using std::bind; 
using std::shared_ptr; 

class Test { 
public: 
    template <typename T> 
    void setCallback(function<void (T, int)> cb); 
}; 

template <typename T> 
void Test::setCallback(function<void (T, int)> cb) 
{ 
    // do nothing 
} 

class TestA { 
public: 
    void testa(int a, int b) { } 
}; 


int main() 
{ 
    TestA testA; 
    Test test; 
    test.setCallback(bind(&TestA::testa, &testA, std::placeholders::_1, std::placeholders::_2)); 
    return 0; 
} 

i pochodzą z poniższej kompilacji błędu:

testtemplate.cpp: In function ‘int main()’:

testtemplate.cpp:29:92: error: no matching function for call to ‘Test::setCallback(std::_Bind_helper)(int, int), TestA, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type)’

testtemplate.cpp:29:92: note: candidate is: testtemplate.cpp:10:7: note: template void Test::setCallback(std::function)

testtemplate.cpp:10:7: note: template argument deduction/substitution failed:

testtemplate.cpp:29:92: note: ‘std::_Bind(TestA*, std::_Placeholder<1>, std::_Placeholder<2>)>’ is not derived from ‘std::function’

używam C++ 11 i g ++ 4.7

+5

Powiedz 'test.setCallback (bind ...)'. Rezultat 'bind' nie jest' std :: function', więc nie ma żadnych argumentów. –

+1

Proszę mi powiedzieć, jak myślisz, w jaki sposób kompilator może dowiedzieć się, do czego wydedukować 'T'. – Xeo

+0

@Xeo Jestem studentem pierwszego roku w szablonie, nie wiem, w jaki sposób dedycje T work.some materiał pomaga? – haipeng31

Odpowiedz

9

, aby dowiedzieć się problem, niech jednostkowego sprawozdania:

auto f = bind(&TestA::testa, &testA, _1, _2); // OK 
test.setCallback(f);       // <<--- Error is here 

setCallback musi znać rodzaj T i nie można go wyprowadzić z f, więc nadać jej typ

test.setCallback<TYPE>(f); // TYPE: int, float, a class, ... 
+0

Szablon jest tak trudny, używam całego popołudnia, aby poradzić sobie z tym problemem, a na koniec, nie mogę rozwiązać, dziękuję za wyjaśnienia. przy okazji, czy możesz dać mi kilka rad o szablonie uczenia się – haipeng31

+2

@ user1679133: Programuj i ćwicz codziennie, to jedyny sposób na naukę koncepcji programistycznych. Tak jak wszyscy. I przeczytaj pytania i odpowiedzi ze Stackoverflow. – deepmax

0

można dokonać odliczenia rodzaj pracy z pewnym wariantem:

template<typename CALLBACK> 
void setCallback(CALLBACK cb) { 
    typedef CALLBACK::first_argument_type T; 
    static_assert(is_same_type<CALLBACK,function<void(T,int)>>::value); 
    ... 
} 

W ten sposób CALLBACK można określić, patrząc na argument. Może mieć kłopoty, jeśli bind nie zwróci std :: function, ale raczej coś, co można rzucić jako jeden. Nie jestem pewny.

Powiązane problemy