Highlighting a Variadic Template

I came across something that I can’t understand, and have not found a way to work normally. What I'm trying to achieve looks relatively simple: I want to compare some data.

The best way to describe is a line of code:

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

I use a tuple as an example. In my case, this data comes from the message object and is retrieved using operator>> . However, this is not a problem.

Here is a minimalist code illustrating the 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...); } }; 

I would normally execute comparaison in the extract() functions, but in order for a simple example, I deleted them.

What I want to achieve is the correct scheduling. Based on this example, I understand that the order of the call should be:

  • Overload for const char *
  • Generic
  • Overload for const char *
  • Generic

However, the output of this test program:

  • Overload: hello
  • Total: 13
  • Assertion failed . The std::is_same runs assert .

I found that const char * overloading will not be called after the general overload has been called once.

Am I missing something?

EDIT: Also not the case, if I define an overload of const char * in front of a generic function, it doesn't even compile.

+5
source share
1 answer

Also note that if I define const char * overloading before a generic function, this does not even compile.

The announcement should be sufficient:

 template <typename... Content> bool extract(MyTuple source, const char *str, Content... content); // <- here template <typename T, typename... Content> bool extract(MyTuple source, T data, Content... content) { 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...); } 

Why?

When viewing a specific name without first declaring the const char* overload is not displayed. Some exceptions to this can be found in the comments below .

+3
source

Source: https://habr.com/ru/post/1207232/


All Articles