2

我有一个“设置”数据类型:

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"看起来它与has typeconst char[2]和 not的事实有关const char*。有人知道如何让它工作吗?

4

2 回答 2

4

问题是V左侧参数获取一种类型,右侧参数获取另一种类型。我怀疑您也希望能够说add(setOfLong, 0)- 但使用该模板您不能。我建议添加一个单独的模板参数来解决这个问题

template <class SetV, class V>
void add(const Set<SetV>& set, const V& value) {}
于 2010-06-25T22:33:52.070 回答
1

还有另一种方法可以解决这个问题(忘记我在哪里看到的......)。

您可以使用“身份”类型包装器让编译器在执行推理时考虑类型。

template <T>
struct Identity {
   typedef T type;
};

然后像这样定义“添加”:

template <class V>
void add(const Set<V>& set, const typename Identity<V>::Type& value) {}

这导致仅基于第一个参数类型推导出“V”。一旦确定了,它就会继续并将其用于第二个参数,这很好。

于 2010-08-24T08:57:00.863 回答