我有一个“设置”数据类型:
template <class V>
struct Set {
void add(const V& value) {}
};
我想写一个Set::add
的顶级函数版本。
template <class V>
void add(const Set<V>& set, const V& value) {}
这对字符串文字不起作用:
Set<const char*> set;
const char* val = "a";
set.add(val); // ok
set.add("a"); // ok
add(set, val); // ok
add(set, "a"); // ERROR
add<const char*>(set, "a"); // ok
错误消息(g ++ 4.2.4):
no matching function for call to ‘add(Set<const char*>&, const char [2])’
它看起来与"a"
类型为const char[2]
而非const char*
的事实有关。有人知道如何让它发挥作用吗?
答案 0 :(得分:4)
问题是V
为左参数获取一种类型,为右参数获取另一种类型。我怀疑你也想说add(setOfLong, 0)
- 但是你不能这样做。我建议添加一个单独的模板参数来解决这个问题
template <class SetV, class V>
void add(const Set<SetV>& set, const V& value) {}
答案 1 :(得分:1)
还有另一种方法可以解决这个问题(忘记我看到的地方......)。
您可以使用“Identity”类型包装器让编译器不在执行推理时考虑类型。
template <T>
struct Identity {
typedef T type;
};
然后像这样定义“添加”:
template <class V>
void add(const Set<V>& set, const typename Identity<V>::Type& value) {}
这导致'V'仅基于第一个参数类型推断出来。一旦确定,它就会继续并将其用于第二个参数,这样可以正常工作。