- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
当我尝试为通用容器(例如 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 = "->";
然后是模板变量(因此具有相同的接口(interface))
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
(std::string
的 constexpr
友好版本)但我遇到了奇怪的链接器错误。
关于c++ - 模板变量特化(针对模板模板类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35027853/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!