частичное упорядочивание вариабельных шаблонных функций clang

В настоящее время я играю в проекте с использованием Boost.ProgramOptions, и мне пришлось создать следующую структуру, чтобы добавить некоторые ограничения для параметра:

template <const char *str1, const char*... str2>
struct restrictedValues
{
...
};

Чтобы проверить эту новую опцию, вы должны перегрузить boost::program_options::validate функция:

template<class T, class charT>
void validate(boost::any& v, const std::vector< std::basic_string<charT> >& xs, T*, long);

Вызов для этой функции проверки следующий:

validate(value_store, new_tokens, (T*)0, 0);

Как уточняется в boost: «Тип цели указывается с помощью параметра, который имеет тип указателя на желаемый тип. Это обходной путь для компиляторов без частичного упорядочивания шаблонов, как и последний параметр long / int».

Я, следовательно, написал свою проверочную версию следующим образом:

template<class charT, const char *... str>
void validate(boost::any &v,
const std::vector<std::basic_string<charT> >& values,
restrictedValues<str...>* /*target_type*/,
int /*unused*/) { ... }

Похоже, моя версия clang (Ubuntu clang версия 3.5.0-4ubuntu2 ~ trusty2 (tags / RELEASE_350 / final) (основанная на LLVM 3.5.0)) просто пропустит мою версию и будет терпеть неудачу в версии по умолчанию. Пока мой gcc ((Ubuntu 4.8.2-19ubuntu1) 4.8.2) успешно компилируется.

РЕДАКТИРОВАТЬ Смотрите живой пример, который показывает другое поведение, credits @dyp:

Жить на Колиру

#include <boost/any.hpp>
#include <vector>
#include <string>
#include <iostream>

template <const char *str1, const char*... str2> struct restrictedValues
{
/*...*/
};

template<class T, class charT>
void validate(boost::any&, const std::vector< std::basic_string<charT> >&, T*, long)
{
std::cout << "default version\n";
}

extern char const client[] = "hello";
extern char const server[] = "world";

template<class charT, const char *... str>
void validate(boost::any &,
const std::vector<std::basic_string<charT> >&,
restrictedValues<str...>* /*target_type*/,
int /*unused*/) {
std::cout << "custom version\n";
}

int main()
{
boost::any a;
std::vector<std::string> xs;
restrictedValues<client, server>* p = 0;
validate(a, xs, p, 0);
}

Более того, тот же процесс, использующий невариантные шаблоны (фиксированное число const char *) для структуры / функции, работает как шарм.

Я не совсем уверен, какой процесс поиска приводит к такой неоднозначной ошибке.
Если бы моя функция не использовала шаблон, он был бы выбран в соответствии с правилами перегрузки, но это не так. Читая правила частичного упорядочения для шаблонных функций, обе функции имеют одинаковую специализацию для параметров шаблона, но я ожидаю, что трюк int / long должен работать. Любая идея о том, как решить эту загадку шаблона?

3

Решение

Обычный подход здесь состоит в том, чтобы заставить ADL работать, используя сильные typedefs.

Я задокументировал это в более старом ответе:


Comments первые комментарии там устарели и ссылаются на старый ответ, который я имел раньше.

0

Другие решения


По вопросам рекламы [email protected]