C++模板参数推理和字符串文字

发布于 2024-09-07 11:09:17 字数 748 浏览 10 评论 0原文

我有一个“set”数据类型:

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*。有人知道如何让它发挥作用吗?

I have a "set" data type:

template <class V>
struct Set {
  void add(const V& value) {}
};

I want to write a top-level function version of Set::add.

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

This doesn't quite work with string literals:

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

The error message (g++ 4.2.4):

no matching function for call to ‘add(Set<const char*>&, const char [2])’

It looks it has something to do with the fact that "a" has type const char[2] and not const char*. Does anybody know how to get this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌路终见情 2024-09-14 11:09:17

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

template <class SetV, class V>
void add(const Set<SetV>& set, const V& value) {}

The problem is that V gets one type for the left parameter, and another type for the right one. I suspect you also want to be able to say add(setOfLong, 0) - but with that template you couldn't. I recommend to add a separate template parameter to solve this

template <class SetV, class V>
void add(const Set<SetV>& set, const V& value) {}
青芜 2024-09-14 11:09:17

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

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

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

然后像这样定义“add”:

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

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

There's another way to solve this problem (forget where I saw it...).

You can use an "Identity" type wrapper to have the compiler not take a type into account when performing inference.

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

Then define "add" like this:

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

This causes 'V' to be deduced solely based on the first argument type. Once that's determined, it goes ahead and uses it for the second argument, which works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文