3

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

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: «Тип цели задается с помощью параметра, который имеет тип указателя на нужный тип. Это временное решение для составителей без частичного упорядочения шаблона, так же, как последний параметр «длинный/Int» «

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

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 (теги/RELEASE_350/final) (на основе LLVM 3.5.0)) просто пропустите мою версию и изящно выйдите из версии по умолчанию. Пока мой gcc ((Ubuntu 4.8. 2-19ubuntu1) 4.8.2) счастливо компилируется.

EDIT См. Живой пример, который показывает различное поведение, кредиты @dyp:

Live On Coliru

#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); 
} 

Кроме того, тот же процесс с использованием не-VARIADIC шаблоны (фиксированное число сопзЬ символ *) для структуры/функция не работает как шарм.

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

+0

Мой плохой неправильный скот. Исправлено. Вопрос все тот же. – Jiwan

+0

Я видел это раньше. И аналогично с точками настройки «serialize/load/save» с параметрами 'operator <<' или Boost Serialization. Честно говоря, я думаю, что это очень интересный вопрос, но он не получит внимания, которого он заслуживает, если не включен SSCCE. Я думаю, что это может быть в <20 строках. Можете ли вы добавить его? – sehe

+0

@sehe [Like this] (http://coliru.stacked-crooked.com/a/18dcea85cb925bae)?(Мне было любопытно: – dyp

ответ

0

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

Я документированы это в старом answer¹:


¹ первые комментарии там устарели и относятся к старому ответ, который я имел прежде.

+0

Я не уверен, что это помогает OP. OP пытается вывести пакет строк, которые clang не может сделать. – dyp

+0

@dyp Я бы не удивился, перегрузившись, чтобы не обращать внимания, потому что std :: vector и std :: basic_string ассоциируют пространство имен std. Я просто излагаю это здесь. Позже у меня могло бы быть время, чтобы на самом деле дать ему тест – sehe

+0

Я думаю, что причина, по которой он терпит неудачу, состоит в том, что в шаблоне класса есть параметр пакета без пакета плюс пакет, а OP выводит только пакет. [работает с соответствующими параметрами в выводе] (http://coliru.stacked-crooked.com/a/6120d23b148930b0); [сбой без дополнительного параметра шаблона в clang] (http://coliru.stacked-crooked.com/a/9b5ca216fd5f7d11) – dyp