Zmierzyłem się z czymś, czego nie rozumiem, ani nie znalazłem sposobu, aby właściwie pracować. To, co próbuję osiągnąć, wygląda stosunkowo prosto: chcę porównać niektóre dane.Ekstrakcje szablonów Variadic
Najlepszy sposób, aby opisać byłaby linia kodu:
std::tuple<const char *, int, const char *, int> my_data =
std::make_tuple("hello", 13, "world", 37);
// Now I want to compare my_data againt some known value.
assert(Test::entry(my_data, "hello", 13, "world", 37));
używam krotki dla dobra przykładu. W moim przypadku dane te pochodzą z obiektu wiadomości i są wyodrębniane za pomocą operator>>
. Jednak nie jest to związane z problemem.
Oto minimalistyczny kod ilustrujący problem.
#include <cstring>
using MyTuple = std::tuple<const char *, int, const char *, int>;
namespace Test
{
// called when we are done
bool extract(MyTuple source)
{
return true;
}
template<typename T,
typename ...Content>
bool extract(MyTuple source, T data, Content... content)
{
if (std::is_same<const char *, T>::value)
assert(0); // why ? :(
std::cout << "Generic: " << data << std::endl;
return extract(source, content...);
}
template<typename ...Content>
bool extract(MyTuple source, const char *str, Content... content)
{
std::cout << "Overloaded: " << str << std::endl;
return extract(source, content...);
}
template<typename ...Content>
bool entry(const std::tuple<const char *, int, const char *, int> &data,
Content... content)
{
return extract(data, content...);
}
};
bym normalnie wykonywać comparaison w funkcjach extract()
, ale dla zachowania przykład prostego, usunąłem je.
Co chcę osiągnąć, to właściwa wysyłka. Opierając się na przykładzie jest to moje zrozumienie, że nazywają zamówienie powinno być:
- Przeciążone dla
const char *
- Generic
- przeciążeniem
const char *
- Generic
Jednakże wyjściu tego testu Program jest następujący:
- Przeciążony: hello
- Ogólny: 13
Assertion failed
. Teststd::is_same
wyzwalaassert
.
Co odkryłem, że przeciążenie const char *
nie zostanie wywołane po jednorazowym wywołaniu generycznego przeciążenia.
Brakuje mi czegoś?
EDYCJA: Nie, jeśli zdefiniuję przeciążenie const char *
przed funkcją ogólną, to nawet nie skompiluje.
To trochę głupie, aby użyć 'std :: make_tuple', kiedy już znasz typ krotki, którą chcesz - cały punkt' make_tuple' ma wydedukować typ krotki z typów inicjalizatorów. Równie dobrze możesz po prostu użyć 'std :: tuple my_data {" hello ", 13," world ", 37};' –
Casey
@Casey Yeah to było tylko dla zilustrowania mojego problem. Moje źródło danych to gniazdo, z którego wydobywam dane. – Xaqq