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 ...);
}
Thử '& GenericThread :: func '. –
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'? –
Cảm ơn rất nhiều @Luc Danton. – Krozark