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})
0

Hi! Could you please add src/class.cpp to SOURCE_FILE in CMakeLists.txt? Does it work in this case?

0
Avatar
Permanently deleted user

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. 

0

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?

0
Avatar
Permanently deleted user

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()'

0

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.

0
Avatar
Permanently deleted user

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?

0

Yes, instead of adding #include "class.cpp" to class.h please add it to a source file where the class is used.

0
Avatar
Permanently deleted user

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() {

0

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? 

 

0

请先登录再写评论。