Reputation: 5618
I am creating a multithreaded class method that needs to call compute
.
void compute(const Me::MyClass<T>& c1, Me:: MyClass<T>& target,std::size_t start);
namespace Me{
template<typename T> class MyClass{
computeMultiThreaded(){
MyClass<T> target = MyClass();
std::size_t n_threads = std::thread::hardware_concurrency();
std::vector<std::tuple<std::size_t, std::size_t>> parts = split_job(n_threads, number_jobs);
std::vector<std::thread> threads;
for (std::size_t ti = 0; ti < n_threads; ti++)
{
// , parts[ti], minCol, this, m2, returnMatrix));
threads.push_back(std::thread(compute,parts[ti]));
}
}
}
}
void compute(const Me::MyClass<T>& c1, Me:: MyClass<T>& target,std::size_t start){
...
}
Now when I try to compile this with compute
defined after MyClass
, Me::MyClass
is not known in the first definition of compute
. When I delete the first declaration, compute
will not be known when creating the thread?
How can I resolve this catch 22?
error: use of undeclared identifier 'Me'
Upvotes: 0
Views: 129
Reputation: 4656
The problem is that the compiler doesn't know about the existence of Me::MyClass
when it reads the declaration of compute
. So all we need to do is tell it that the class exists!
namespace Me {
template<typename T> class MyClass;
}
you can later define Me::MyClass
like so
template<typename T> class Me::MyClass {
// insert your class definition
};
The first snippet is a class declaration, the second is a class definition.
Upvotes: 4
Reputation: 3911
You can "forward-declare" the namespace and including forward declaration of your class then later do your job correctly:
namespace Me {
template<typename T> class MyClass;
template <class T>
void compute(const MyClass<T>& c1, MyClass<T>& target, std::size_t start);
}
Then later:
//template<class T>
//void compute(const Me::MyClass<T>& c1, Me::MyClass<T>& target, std::size_t start); // Correct but it is already declared in namespace "Me"
Now the definition:
namespace Me {
template<typename T> class MyClass
{
void computeMultiThreaded() { // I added void here so you should add a return type
MyClass<T> target = MyClass();
std::size_t n_threads = std::thread::hardware_concurrency();
std::vector<std::tuple<std::size_t, std::size_t>> parts = split_job(n_threads, number_jobs);
std::vector<std::thread> threads;
for (std::size_t ti = 0; ti < n_threads; ti++)
{
// , parts[ti], minCol, this, m2, returnMatrix));
threads.push_back(std::thread(compute, parts[ti]));
}
}
}; // you missed also the semicolon in your example
}
template <class T>
void compute(const Me::MyClass<T>& c1, Me::MyClass<T>& target, std::size_t start) {
}
I wish this works for you.
Upvotes: 0
Reputation: 109289
Declare MyClass
before the declaration of compute
. And compute
needs to be a function template if you want it to have arbitrary MyClass<T>
parameter types.
namespace Me
{
template<typename T>
class MyClass;
}
template<typename T>
void compute(const Me::MyClass<T>& c1, Me:: MyClass<T>& target,std::size_t start);
Upvotes: 5