开发者

C++ template argument inference and string literals

开发者 https://www.devze.com 2023-01-04 23:53 出处:网络
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.

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.

t开发者_运维技巧emplate <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?


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) {}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消