Вывод аргументов шаблона C ++ и строковые литералы - PullRequest
2 голосов
/ 26 июня 2010

У меня есть «установленный» тип данных:

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*. Кто-нибудь знает, как заставить это работать?

Ответы [ 2 ]

4 голосов
/ 26 июня 2010

Проблема в том, что V получает один тип для левого параметра и другой тип для правого.Я подозреваю, что вы также хотите иметь возможность сказать add(setOfLong, 0) - но с этим шаблоном вы не можете.Я рекомендую добавить отдельный параметр шаблона, чтобы решить эту проблему

template <class SetV, class V>
void add(const Set<SetV>& set, const V& value) {}
1 голос
/ 24 августа 2010

Есть еще один способ решить эту проблему (забудьте, где я ее видел ...).

Вы можете использовать оболочку типа "Identity", чтобы компилятор не учитывал тип при выполнении логического вывода.

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

Затем определите «добавить» следующим образом:

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

Это приводит к тому, что 'V' выводится исключительно на основе первого типа аргумента. Как только это определено, оно идет вперед и использует его для второго аргумента, который отлично работает.

...