Я использую библиотеку C ++ ( strf ), которая где-то внутри имеет следующий код:
namespace strf {
template <typename ForwardIt>
inline auto range(ForwardIt begin, ForwardIt end) { /* ... */ }
template <typename Range, typename CharT>
inline auto range(const Range& range, const CharT* sep) { /* ... */ }
}
Теперь я хочу использовать strf::range<const char*>(some_char_ptr, some_char_ptr + some_length)
в своем коде. Но если я это сделаю, я получу следующую ошибку (с NVCC CUDA 10.1):
error: more than one instance of overloaded function "strf::range" matches the argument list:
function template "auto strf::range(ForwardIt, ForwardIt)"
function template "auto strf::range(const Range &, const CharT *)"
argument types are: (util::constexpr_string::const_iterator, util::constexpr_string::const_iterator)
Код библиотеки, вероятно, можно изменить, чтобы избежать этого (например, используя:
inline auto range(const typename std::enable_if<not std::is_pointer<typename std::remove_cv<Range>::type>::value, Range &>::type range, const CharT* sep)
чтобы Range
не указатель); но я не могу сделать это изменение прямо сейчас. Вместо этого я хочу как-то указать компилятору, что я действительно хочу иметь только один аргумент шаблона, а не один указанный и еще один выведенный.
Я могу это сделать?
Был бы признателен за ответы для C ++ 11 и C ++ 14; Ответы C ++ 17, включающие руководства по выводам, менее актуальны, но если они у вас есть, отправьте их (для будущих версий NVCC ...)
Обновление: Сама библиотека strf была обновлена, чтобы обойти эту ситуацию, но вопрос остается неизменным.
char*
но не является ли это решением?Ответы:
Тогда звони
range1
вместоstrf::range
.range1_ptr<T>(...)
всегда может использоваться для явного вызова шаблона с одним аргументом шаблона, но не делает никаких выводов из аргументов.range1
повторяет вычет из исходногоstrf::range
шаблона.Это работает, потому что [temp.deduct.funcaddr] / 1 говорит, что вычитание аргумента шаблона при получении адреса функции без целевого типа преобразования выполняется для каждого шаблона функции-кандидата, как если бы списки параметров и аргументов гипотетического вызова были опорожнить. Таким образом, второй аргумент шаблона не может быть выведен для второй перегрузки с двумя параметрами шаблона. Единственный оставшийся кандидат - это первая перегрузка, которая будет выбрана в качестве цели указателя функции.
Пока не существует второго шаблона функции-кандидата, для которого можно сформировать действительный идентификатор шаблона только с одним аргументом,
range1_ptr
всегда можно использовать для вызова шаблона функции, принимающего один аргумент однозначно. В противном случае создание экземпляраrange1_ptr
даст ошибку из-за неоднозначности.источник
strf::range<T>
?pretty_please_with_sugar_on_top()
? ... C ++ иногда бывает таким странным ...Как насчет прохождения через
using
?источник
range()
совместима только первая версияtpf
; другой случай может быть другим.tfp x = &strf::range<char const *>;
); таким образом, я полагаю, у вас есть общее решение, почти эквивалентное грецкому орехуРешение
1) прежде всего, вы должны указать тип для второго аргумента, например
(char *)(some_char_ptr + some_length)
2) не используйте
const
для обоих, это работает хорошо:Вы можете попробовать заменить
(char *)
с(const char *)
слева или справа, он все еще работает.источник
const
данные.