Проблема шаблона Variadic, соответствующая константе и станд. неконстанты:: последовательность

Я испытываю затруднения при строительстве variadic шаблона, где функции расширения правильно соответствуют и неконстанте и константе станд.:: последовательность . У меня есть универсальная функция соответствия, которая вызвана вместо этого в некоторых случаях.

Я уменьшил код до ниже примера. Вещи, которые не являются последовательностью, должны закончиться в родовой функции. Вещи, которые являются последовательностью, должны закончиться во второй функции, которую дополнительно "НАТЯГИВАЕТ" продукция.

#include 
#include 

template
void extend_exception( X & ex, T&& value )
{
    ex << value << std::endl;
}

template
void extend_exception( X & ex, std::string && value )
{
    ex << "STRING: " << value << std::endl;
}

template
void extend_exception( X & ex, TF&& f, TR&& ... rest )
{
    extend_exception( ex, std::forward(f) );
    extend_exception( ex, std::forward<tr>(rest)... );
}

int main()
{
    extend_exception( std::cout, std::string( "Happy" ) );
    std::string var( "var" );
    extend_exception( std::cout, var );
    extend_exception( std::cout, var, std::string( "Combo" ),  const_cast(var));
    return 0;
}

In the version above the two var uses do not get passed to the string function. I have tried various other ways of specifying the parameter but none seem to do the trick: std::string && value, std::string const & value, std::string const && value. I did also try just std::string & value and then the non-const strings match, but not the const ones. This provides me with at least a workaround by having two different functions, but I suspect I shouldn't need to do this.

How do I write a single function here that will be called for const, non-const, and temporary string objects?

I'm using g++ 4.6.3

1
nl ja de
@Griwes, да, стоимостью работает, но я don' t хотят, копируя вещи напрасно.
добавлено автор edA-qa mort-ora-y, источник
Просто прохождение стоимостью, кажется, работает, хотя я сомневаюсь относительно it' s во всяком случае "исправляют".
добавлено автор Griwes, источник

4 ответы

This is pretty tricky, T&& is a so called universal reference but std::string&& is not (no type deduction is involved). See here for a good explanation. Here is a fix:

template
void extend_exception_( X & ex, T&& value, ... )
{
  ex << value << std::endl;
}

template::type>::value>::type>
void extend_exception_( X & ex, T && value, int )
{
  ex << "STRING: " << value << std::endl;
}

template  using identity = T;

template
void extend_exception( X & ex, R&& ... rest )
{
  identity{false,(extend_exception_(ex, std::forward(rest), 0), false)...};
}

int main()
{
  extend_exception( std::cout, std::string( "Happy" ) );
  std::string var( "var" );
  extend_exception( std::cout, var );
  extend_exception( std::cout, var, std::string( "Combo" ) );
}
4
добавлено
Я неспособен проверить это, так как псевдонимы шаблона - not' t поддержанный до GCC 4.7 (ваша декларация идентичности). Можно ли проверить, что мой добавленный параметр в моем примере (последняя возможность к extend_exception с const_cast) все еще также работает с этим кодом?
добавлено автор edA-qa mort-ora-y, источник
Вы, вероятно, хотите использовать станд.:: распад вместо станд.:: remove_reference иначе is_same тест подводит для станд. константы:: последовательность . Использование Aternatively станд.:: remove_cv и станд.:: remove_reference , но станд.:: распад меньше печатает и эквивалентный в этом случае.
добавлено автор Jonathan Wakely, источник
Да, разобраться в нем без SFINAE требует трех функций для каждого специализированного типа (станд.:: натяните здесь). ideone.com/o3wxsl
добавлено автор Mooing Duck, источник
Что идентичность ?
добавлено автор Seth Carnegie, источник
О, возгласы, плохое чтение, жаль.
добавлено автор Seth Carnegie, источник
Определенный 5 линий выше it' s использование: идентичность является идентичностью;)
добавлено автор ipc, источник
@JonathanWakely: Согласитесь, спасибо.
добавлено автор ipc, источник

You can't bind a non-rvalue to an rvalue-reference, so string&& doesn't work, but const std::string& works for var. However, var is not const, so the shortest path to an overload that works is collapsing T&& to std::string& and taking the first one.

Необходимо будет выяснить типы, которые являются взаимоисключающими или используют SFINAE, чтобы написать два, которые исключают друг друга на правильном типе аргументов.

2
добавлено

This is because your string version only captures strings passed as rvalues. lvalues will get passed to the generic function. There is a huge difference between T&& and string&&, or more general T&& and U&&, if T is a template parameter and U is not (meaning, U is some specified type). See Scott Meyers' notes on universal references

То, что необходимо сделать, чтобы заставить функцию работать, как вы хотите, добавляет еще одна перегрузка:

template
void extend_exception( X & ex, std::string const& value )
{
  ex << "STRING: " << value << std::endl;
}
2
добавлено
&& также won' t ловят изменчивые ссылки. Необходимо добавить два другие перегрузки.
добавлено автор Mooing Duck, источник

Я пересмотрел проблему и предложил решение, которое включает использование маркера класса. Я написал статью с полное решение/обсуждение.

0
добавлено
pro.cxx
pro.cxx
3 049 участник(ов)

C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. Не хамим, не переходим на личности, не вбрасываем утверждения без доказательств 2. No Ads, offtop, flood Объявления о вакансиях и евенты - в лс @AlexFails https://t.me/ProCxx/259155

supapro.cxx
supapro.cxx
1 925 участник(ов)

Чат для тех, кто немного знает C++, простые вопросы по реализации, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат по обсуждению всего — @fludpac

C++ Russia
C++ Russia
384 участник(ов)

Сообщество разработчиков C++ в Telegram.

cxx.Дискуссионная
cxx.Дискуссионная
298 участник(ов)

это не двач, общайтесь вежливо; разговор на почти любые темы; Не согласны с баном? В лс @AlexFails, @ivario

C++ для маленьких и тупых
C++ для маленьких и тупых
105 участник(ов)

Лоу левел (по среднему IQ участников) чатик ExtremeCode @extremecode Флудилка @extremecode_rest