2013-05-06 44 views
5

Tôi cố gắng gọi một hàm thành viên của một đối tượng bằng cách sử dụng một chuỗi.Mẫu chức năng thành viên C++ Mẫu variadic

Nếu chức năng không có một mẫu variadic (args ... args), không có vấn đề, nó hoạt động:

Hãy xem xét hai lớp:

GeneticEngine

template <class T> 
class GeneticEngine 
{ 
    template <typename ... Args> 
    T* run_while(bool (*f)(const T&),const int size_enf,Args& ... args) 
    { 
     std::thread(&GeneticThread<T>::func,islands[0],f,size_enf); 
     /* Some code */ 
     return /* ... */ 
    } 
    private: 
     GeneticThread<T>** islands; 


} 

GeneticThread

template <class T> 
class GeneticThread 
{ 
    void func(bool (*f)(const T&),const int size_enf) 
    { 
     /* Some code */ 
    }; 
} 

Với điều này, OK.


Bây giờ, tôi thêm một mẫu variadic đến các chức năng tương tự:

GeneticEngine

template <class T> 
class GeneticEngine 
{ 
    template <typename ... Args> 
    T* run_while(bool (*f)(const T&,Args& ...),const int size_enf,Args& ... args) 
    { 
     std::thread(&GeneticThread<T>::func,islands[0],f,size_enf,args ...); 
     /* Other code ... */ 
    } 
    private: 
     GeneticThread<T>** islands; 
} 

GeneticThread

template <class T> 
class GeneticThread 
{ 
    template <typename ... Args> 
    void func(bool (*f)(const T&,Args& ...), const int size_enf, Args& ... args) 
    { 
     /* Code ... */ 
    }; 
} 

Với mã này, GCC không biên dịch: (xin lỗi vì thông báo lỗi này)

g++ main.cpp GeneticEngine.hpp GeneticThread.hpp Individu.hpp GeneticThread.o -g -std=c++0x -o main.exe 
In file included from main.cpp:2:0: 
GeneticEngine.hpp: In instantiation of ‘T* GeneticEngine<T>::run_while(bool (*)(const T&, Args& ...), int, Args& ...) [with Args = {}; T = Individu]’: 
main.cpp:24:78: required from here 
GeneticEngine.hpp:20:13: erreur: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, GeneticThread<Individu>*&, bool (*&)(const Individu&), const int&)’ 
GeneticEngine.hpp:20:13: note: candidates are: 
In file included from GeneticThread.hpp:14:0, 
      from GeneticEngine.hpp:4, 
      from main.cpp:2: 
/usr/include/c++/4.7/thread:131:7: note: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...) 
/usr/include/c++/4.7/thread:131:7: note: template argument deduction/substitution failed: 
In file included from main.cpp:2:0: 
GeneticEngine.hpp:20:13: note: couldn't deduce template parameter ‘_Callable’ 
In file included from GeneticThread.hpp:14:0, 
      from GeneticEngine.hpp:4, 
      from main.cpp:2: 
/usr/include/c++/4.7/thread:126:5: note: std::thread::thread(std::thread&&) 
/usr/include/c++/4.7/thread:126:5: note: candidate expects 1 argument, 4 provided 
/usr/include/c++/4.7/thread:122:5: note: std::thread::thread() 
/usr/include/c++/4.7/thread:122:5: note: candidate expects 0 arguments, 4 provided 

Tôi thực sự không hiểu tại sao sự khác biệt này lại gây ra lỗi này. Và tôi không thể sửa nó.


Trong cả hai main.cpp là như thế:

/* Individu is another class */ 

int pop_size = 1000; 
int pop_child = pop_size*0.75; 

GeneticEngine<Individu> engine(/*args to constructor*/); 

bool (*stop)(const Individu&) = [](const Individu& best){ 
    return false; 
}; 
Individu* best = engine.run_while(stop,pop_child); 

tôi sử dụng: «phiên bản gcc 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)»


Tôi đã thử:

std::thread(&GeneticThread<T>::func<Args...>, islands[0], f, size_enf, args ...); 

Bây giờ tôi có một lỗi:

GeneticEngine.hpp: In member function ‘T* GeneticEngine<T>::run_while(bool (*)(const T&, Args& ...), int, Args& ...)’: 
GeneticEngine.hpp:20:53: erreur: expansion pattern ‘((& GeneticThread<T>::func) < <expression error>)’ contains no argument packs 
GeneticEngine.hpp:20:24: erreur: expected primary-expression before ‘(’ token 
GeneticEngine.hpp:20:53: erreur: expected primary-expression before ‘...’ token 



template <typename ... Args> 
T* run_while(bool (*f)(const T&,Args& ...), const int size_enf, Args& ... args) 
{ 

    void (GeneticThread<T>::*ptm)(bool (*)(T const&, Args&...), int, Args&...) = &GeneticThread<T>::func; 
    std::thread(ptm, islands[0], f, size_enf, args ...); 
} 
+0

Thử '& GenericThread :: func '. –

+1

Dường như GCC gặp sự cố với việc mở rộng mẫu. Bạn có thể thử 'auto ptm = & GenericThread :: func ;' hoặc 'void (GenericThread :: * ptm) (bool (*) (T const &, Args & ...), int, Args & ...) = & GenericThread :: func; 'riêng biệt, sau đó chuyển' ptm' vào hàm tạo 'std :: thread'? –

+0

Cảm ơn rất nhiều @Luc Danton. – Krozark

Trả lời

2

Hãy thử:

std::thread(&GeneticThread<T>::func<Args...>, islands... 

func bây giờ là một hàm mẫu. Bạn phải chỉ định các tham số mẫu của nó để có thể lấy địa chỉ của nó.

+0

Tôi thử, nhưng một lỗi khác xuất hiện (xem phần chỉnh sửa). – Krozark

Các vấn đề liên quan