【发布时间】:2019-04-28 08:48:58
【问题描述】:
在下面的代码示例中,我定义了一个类 DT(我的默认类型),我希望它能够作为任意模板的参数传递。在此示例中,我将 DT 作为 std::map 的键和值参数传递。我实际上并没有尝试实例化 map
#include <iostream>
#include <map>
using namespace std;
class DT {};
template <typename T>
string f() {
return "foo";
}
int main() {
cout << f<map<DT,DT>>() << endl;
return 0;
}
使用 g++ 似乎可以正常工作。我什至尝试为所有四个映射参数传递 DT(覆盖默认比较器和分配器类型)。仍然有效。但我担心这种技术可能会因其他模板或其他编译器而失败。所以我的问题是:对于任何符合 c++11 标准(及更高标准)的 c++ 编译器上的任何模板来说,这总是安全的。换句话说,将完全不兼容的类型作为模板的参数传递是否总是安全的,只要您从不尝试实例化该模板?
如果您想知道我到底为什么要做这样的事情,我正在尝试设置一个可以存储类型相关配置字符串的类。它将有这两种方法:
template<typename T>
const string& get<T>() const;
template<typename T>
void set<T>(const string& value);
它在很大程度上令我满意。它有几个不错的功能。例如,类型 int、const int、int&、const int& 等都被视为同一类型(这是我想要的)。如果没有找到更具体的派生类型的条目,您可以存储基类的配置字符串,以后可以通过派生类型检索该配置字符串。但是对于 std::map 的情况,我希望能够使用 map
【问题讨论】:
-
我知道这是语言律师标签,但为什么不使用您自己的标签类型而不是
std::map? -
@super 我不明白这个问题。如果目标是将配置与任何可能的类型相关联,那么它也需要处理
std:;map(因为这是可能的类型之一)。 -
@melpomene 问题指出
std::map<DT, DT>是不兼容的,因为它实际上无法使用,所以我认为它的目的是用唯一类型标记get/set。 -
@super, @melpomene:是的,我只想通过调用
config.set<std::map<DT,DT>>("foo")将配置字符串绑定到类型std::map<DT, DT>。然后,如果有人在以前没有为类型std::map<int,int>存储条目时调用config.get<std::map<int,int>>(),它将返回为std::map<DT,DT>存储的值。我当然可以添加operator<()等以使 DT 成为有效密钥,但其他模板上的其他模板参数可能有其他我无法预料的要求。 -
@MatthewBusche 出于好奇,您的
get<>()和set<>()方法是包装对模板化单例(字符串)的访问,还是使用实例绑定配置动态扩展给定的Config实例基于set<>()和get<>()调用不同类型的字符串?
标签: c++ templates language-lawyer