加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 模板变量的专业化(用于模板模板类)

发布时间:2020-12-16 07:15:24 所属栏目:百科 来源:网络整理
导读:当我尝试为一个通用容器专门化一个模板变量时(例如std :: list ...,而不是特定的一个,例如std :: list double)我得到了 gcc 5.3的链接错误(但是不与clang 3.5) /tmp/ccvxFv3R.s: Assembler messages:/tmp/ccvxFv3R.s:206: Error: symbol `_ZL9separator' is
当我尝试为一个通用容器专门化一个模板变量时(例如std :: list< ...>,而不是特定的一个,例如std :: list< double>)我得到了 gcc 5.3的链接错误(但是不与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';

}

(这与clang 3.5很好地编译并且按预期工作.此外,可变参数模板不是导致问题的原因,我尝试使用非可变参数模板).

如果这不是gcc中的错误,你认为有没有解决方法?我试图使用类专门化,但它也不可能:

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 = "->";

解决方法

这似乎是gcc的一个问题.解决方法(使用类模板),如@ T.C.建议.

template<class T>
struct sep{
    static const std::string value;
};
template<class T>
const std::string sep<T>::value = ",";

template<typename... Ts>
struct sep<std::list<Ts...>>{
    static const std::string value;
};
template<typename... Ts>
const std::string sep<std::list<Ts...>>::value = "<->";

template<typename... Ts>
struct sep<std::forward_list<Ts...>>{
    static const std::string value;
};
template<typename... Ts>
const std::string sep<std::forward_list<Ts...>>::value = "->";

以后是模板变量(所以具有相同的接口)

template<typename T> std::string const separator = sep<T>::value;

这适用于gcc和clang.

或者@ T.C.建议使用静态函数成员而不是静态成员(代码少)

template<class T>
struct sep{
    static std::string value(){return ",";}
};
template<typename... Ts>
struct sep<std::list<Ts...>>{
    static std::string value(){return "<->";}
};

template<typename... Ts>
struct sep<std::forward_list<Ts...>>{
    static std::string value(){return "->";}
};
...
template<typename T> std::string const separator = sep<T>::value();

或者使用constexpr const char *

template<class T>
struct sep{static constexpr const char* value = ",";};

template<typename... Ts>
struct sep<std::list<Ts...>>{static constexpr const char* value = "<->";};

template<typename... Ts>
struct sep<std::forward_list<Ts...>>{static constexpr const char* value = "->";};
...
template<typename T> std::string const separator = sep<T>::value;

我试图使用const_str(一个constexpr友好版本的std :: string),但我得到了奇怪的链接器错误.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读