Member function overload or template specialization problem

I am trying to call the overloaded member function of table::scan_index(std::string, ...) without success. For clarity, I deleted all the inappropriate code.

I have a class called table that has an overloaded / templated member function called scan_index() to treat rows as a special case.

 class table : boost::noncopyable { public: template <typename T> void scan_index(T val, std::function<bool (uint recno, T val)> callback) { // code } void scan_index(std::string val, std::function<bool (uint recno, std::string val)> callback) { // code } }; 

Then there is a hitlist class that has several template member functions that call table::scan_index(T, ...)

 class hitlist { public: template <typename T> void eq(uint fieldno, T value) { table* index_table = db.get_index_table(fieldno); // code index_table->scan_index<T>(value, [&](uint recno, T n)->bool { // code }); } }; 

And finally, the code that discards all of this:

 hitlist hl; // code hl.eq<std::string>(*fieldno, p1.to_string()); 

The problem is that instead of calling table::scan_index(std::string, ...) it calls the template version. I tried to use both overload (as shown above) and a specialized function template (below), but nothing works. After looking at this code for several hours, I feel like I'm missing something obvious. Any ideas?

  template <> void scan_index<std::string>(std::string val, std::function<bool (uint recno, std::string val)> callback) { // code } 

Update: I reset the <T> decoration from the scan_index() call. As a result, it turned out that calls with the string parameter are just fine, but calls with other types (for example, double) led to the following error:

 cannot convert parameter 1 from 'double' to 'std::string' 

So, I returned to using specialized specialization. Now I get this error:

 error C2784: 'void table::scan_index(T,std::tr1::function<bool(uint,T)>)' : could not deduce template argument for 'std::tr1::function<bool(uint,T)>' from '`anonymous-namespace'::<lambda5>' 

FYI: I am using VC ++ 10.0

Solution: I fixed this problem by dropping the scan_index() template function from the table class and simply writing down four overloaded functions (three of which are identical, except for the signature). Fortunately, they are all quite short (less than ten lines), so this is not so bad.

+4
source share
4 answers

You explicitly call the template element here:

 index_table->scan_index<T>(value, [&](uint recno, T n)... 

Since value is a template parameter, you should replace it as follows:

 index_table->scan_index(value, [&](uint recno, T n)... 
+7
source

You do not have to explicitly specify a template argument - you must leave it to display the template argument and enable overloading. This should allow the overload that you sent in the very original code that you need to take and use.

+3
source

prepared this simplified test (sorry, I don't have a C ++ 0x compiler):

 class table { public: template <typename T> void scan_index(T val) { std::cout << "template\n"; } template <> void scan_index<int>(int val) { std::cout << "specialization\n"; } void scan_index(int val) { std::cout << "overloaded\n"; } }; class hitlist { public: template <typename T> void eq(T value) { table tbl; tbl.scan_index<T>(value); } }; int main(int argc, char* argv[]) { int i = 0; hitlist hl; hl.eq(i); return 0; } 

the conclusion is "specialization" (VC9). because hitlist :: eq explicitly uses the template version, so only specialized specialization will be considered. if you change tbl.scan_index<T>(value); on tbl.scan_index(value); , the overloaded version will be called.

tbh I don’t know why your specialized specialization does not work, perhaps due to lambda, not full support for C ++ 0x? which compiler?

+1
source

Is the template specialization something like:

 template <typename T> void scan_index(T val, std::function<bool (uint recno, T val)> callback) { // code } template <> void scan_index(std::string val, std::function<bool (uint recno, std::string val)> callback) { // code } 

Thus, the C ++ compiler recognizes that scan_index has a specialization, and does not look for an overloaded method. And I believe that if you wanted you to be able to code, you should probably put specialized code in front of the template as follows:

  void scan_index(std::string val, std::function<bool (uint recno, std::string val)> callback) { // code } template <typename T> void scan_index(T val, std::function<bool (uint recno, T val)> callback) { // code } 
0
source

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


All Articles