clion does not see usages of data variable for template class
已回答
This is small example, I have a template class which declared in ".h" file, and the implementation of its function is in ".c" file and file "c" is included in ".h" file.
---------------------------------
"src/example.h"
#ifndef EXAMPLE_CLASS_H
#define EXAMPLE_CLASS_H
template<class T>
class Class {
public:
Class();
explicit Class(const T& data);
void Proceed();
private:
T data;
};
#include "class.cpp"
#endif //EXAMPLE_CLASS_H
---------------------------------
"src/example.cpp"
#include "example.h"
template<class T>
Class<T>::Class() : data(0) {}
template<class T>
Class<T>::Class(const T& data) : data(data) {}
template<class T>
void Class<T>::Proceed() {
std::cout << data << '\n';
}
---------------------------------
"src/main.cpp"
#include <bits/stdc++.h>
#include "class.h"
using namespace std;
int main() {
Class<double> cc(5);
cc.Proceed();
return 0;
}
I can CTRL-click on method Proceed() in cpp file and it gets me to the declaration of it in h file. However, when I'm trying to do the same with "T data" variable, it does not found any usages of it. Working on large project it makes me really annoying, I can't find what methods using the data :( My CMakeLists.txt file:
cmake_minimum_required(VERSION 3.7)
project(example)
set(CMAKE_CXX_STANDARD 11)
include_directories(src)
set(SOURCE_FILES src/main.cpp src/class.h)
add_subdirectory(test)
add_executable(example ${SOURCE_FILES})
请先登录再写评论。
Hi! Could you please add src/class.cpp to SOURCE_FILE in CMakeLists.txt? Does it work in this case?
Hi! Thanks for the answer! If I add src/class.cpp I can see all the usage of T data, however the problem is that I cannot add this source as redefinition problem. The class is the template class and implementation in .cpp is included to .h file, so I can not compile .cpp file.
I'm not sure why you need to have #include "class.cpp" in class.h if you have #include "class.h" in class.cpp. Could you please remove #include "class.cpp" from class.h and add src/class.cpp to SOURCE_FILES in CMakeLists.txt?
When remove #include "class.cpp" and add src/class.cpp to SOURCE_FILE error happened
C:/Users/home/Documents/clion/example/src/main.cpp:6: undefined reference to `Class<double>::Class(double const&)'
C:/Users/home/Documents/clion/example/src/main.cpp:7: undefined reference to `Class<double>::Proceed()'
Sorry for my inattentiveness. Please add #include "class.cpp" to main.cpp after #include "class.h". It should work this way.
In other words:
class.h should be included in class.cpp;
class.h and class.cpp should be included in main.cpp;
src/main.cpp, src/class.h, src/class.cpp should be added to a target in CMakeLists.txt.
Now it works! Thanks a lot!
So, whenever I use my Class I should include both class.cpp and class.h files, and for other template classes I should do the same?
Yes, instead of adding #include "class.cpp" to class.h please add it to a source file where the class is used.
Well, thanks. But now the problem is that this approach does not support mutual include.
If I have two classes template Class1<T> and template Class2<T> and .h and .cpp files associated with them,
I cannot include "class1.h" and "class1.cpp" in "class2.h" file and "class2.h" and "class2.cpp" in "class1.h" file.
The errors look like
error: 'Class2' does not name a type
error: expected initializer before '<' token
void Class2<T>::Proceed() {
Ok, let me explain the background. CLion takes all the information about the files in project from CMake. Thus, unfortunately, if a file is not added explicitly to CMake, CLion doesn't know that the file belongs to the project. We understand that it is not required by CMake and we have the issue in our tracker: https://youtrack.jetbrains.com/issue/CPP-270. Feel free to comment or upvote.
Summary: in order to get the file properly highlighted you need to add the file to some CMake target. So you need either to reorganise your code in the way when class.cpp can be added to a target or to create two targets - one real target (without class.cpp) which you will build/execute and the other target (with all files added to it) which you won't build/execute. Please note that the second option is a workaround, and this workflow is not really supported. So I'd rather suggest you to reorganise your code if it's possible. How are Class1<T> and Class2<T> interacted?