assume a template variable in data.h:
template <class T>
struct Data
{
Data() = delete;
Data(T initValue) : value(initValue){}
T value;
};
template<class T>
extern Data<T> data;
there is a specialization definition of this variable for int
in data_def.cpp:
#include "data.h"
template<>
Data<int> data<int>{55};
usage in main.cpp:
#include <iostream>
#include "data.h"
int main() {
std::cout << data<int>.value << "n";
return 0;
}
full project on godbolt
The code works on GCC but clang complains:
warning: instantiation of variable ‘data’ required here, but no definition is available [-Wundefined-var-template].
Probably it expects a declaration of a template variable specialization.
What is the right way (according to the standard) to define a template variable specialization in one translation unit and use it in a different one?
If a declaration of a variable specialization is necessary what is the syntax for this?
In standard I did not find an answer.
I can use only C++17 (if it matters).
A tempting syntax template<> extern Data<int> data<int>;
is wrong (GCC does not accept it and clang devs are going to do the same)
update:
@Oersted and @user12002570 suggested a WA with inline. It’s not a full solution but a valid WA
13
If a declaration of a variable specialization is necessary what is the syntax for this?
You can just use inline
in the definition of the specialization in the header file. That way you won’t need to define it in a separate source file. Demo
Change data.h to:
#pragma once
template <class T>
struct Data
{
Data() = delete;
Data(T initValue) : value(initValue){}
T value;
};
template<class T>
extern Data<T> data;
//---------vvvvvv--------------------------inline added here
template<> inline Data<int> data<int>{55};