У меня есть два оператора шаблона в классе:Каковы правила выбора между методом вариационного шаблона и обычным методом шаблонов?
template<class T>
size_t operator()(const T& t) const {
static_assert(boost::is_pod<T>(), "Not a POD type");
return sizeof t;
}
template<typename... T>
size_t operator()(const boost::variant<T...>& t) const
{
return boost::apply_visitor(boost::bind(*this, _1), t);
}
проходит boost::variant<some, pod, types, here>
в качестве аргумента этих операторов. GCC 4.8 и llvm 6.0 скомпилируют код, выбрав boost::variant
параметризованный оператор. gcc 4.7 выбирает const T& t
параметризованный оператор и, следовательно, не может скомпилироваться из-за статического утверждения.
Итак, у меня есть вопрос, каковы правила выбора между этими двумя? Я думаю, что gcc 4.7 должен иметь ошибку, но у меня нет никаких доказательств.
Это не * выбор наилучшего соответствия *, как в ранжировании конверсий. Это частичный порядок, который делает последнюю перегрузку предпочтительной для аргумента boost :: variant. –
@PiotrS. Я думаю, что ваш ответ противоречит цитируемому разделу. Я также не уверен, что PO - проблема с перегрузками, объявленными внутри одного класса. (Этот трюк часто используется для рекурсивных/вариационных рассылок, которые не будут работать в области пространства имен) – sehe
Что такое встречный раздел? после создания экземпляров обоих шаблонов функций они неотличимы друг от друга, поэтому PO считается: «* F1 и F2 являются специализированными шаблонами функций, а шаблон функции для F1 более специализирован, чем шаблон для F2 в соответствии с правилами частичного упорядочения, описанными в 14.5 .6.2. "* –