When I try specialize a template variable for a generic container (e.g. std::list<...>
, and not for an specific one, e.g. std::list<double>
) I get a link error with gcc 5.3
(but not with clang 3.5
)
/tmp/ccvxFv3R.s: Assembler messages:
/tmp/ccvxFv3R.s:206: Error: symbol `_ZL9separator' is already defined
http://coliru.stacked-crooked.com/a/38f68c782d385bac
#include<string>
#include<iostream>
#include<list>
#include<forward_list>
#include<vector>
template<typename T> std::string const separator = ", ";
template<typename... Ts> std::string const separator<std::list<Ts...> > = "<->";
template<typename... Ts> std::string const separator<std::forward_list<Ts...>> = "->";
int main(){
std::cout << separator<std::vector<double>> << '\n';
std::cout << separator<std::list<double>> << '\n';
std::cout << separator<std::forward_list<double>> << '\n';
}
(This compiles well with clang 3.5
and works as expected. Also the variadic template is not what causes the problem, I tried with a non-variadic template).
If this is not a bug in gcc
, do you think is there a work around? I tried to use class specialization but it is not possible either:
template<class T>
struct separator{
static std::string const value;
};
template<class T>
std::string const separator<T>::value = ", ";
template<typename... Ts>
std::string const separator<std::list<Ts...>>::value = "<->";
template<typename... Ts>
std::string const sep<std::forward_list<Ts...>>::value = "->";
This seems to be a problem with
gcc
. Workaround (use class templates), like @T.C. suggested.And later a template variable (so to have the same interface)
This works in both
gcc
andclang
.Or also suggested by @T.C., use a static function member instead of a static member (less code)
Or use
constexpr const char*
I tried to use
const_str
(aconstexpr
-friendly version ofstd::string
) but I got strange linker errors.