Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ SFINAE Resolution Order

I have two functions

template <typename... Args>
void foo(Args&&... args) { /* ... */ }

template <typename... Args>
void foo(const std::string& name, Args&&... args) { /* ... */ }

Currently all calls like foo("bar", /* arguments */) try to go to the first function instead of the second. I want to reorder these functions so that the SFINAE finds the second before the first. I cannot use std::enable_if to check for char array/string because the Args... pack might contain std::string& or const char (&) []. How do I do this?

like image 751
ssb Avatar asked Dec 13 '22 21:12

ssb


1 Answers

The issues here is that "bar" is not a std::string. No amount of reordering is going to get void foo(const std::string& name, Args&&... args) called since that would require a conversion while void foo(Args&&... args) will produce an exact match.

One workaround you can use the literal string operator and make "bar" a string using "bar"s. This does require changing

template <typename... Args>
void foo(const std::string& name, Args&&... args) { /* ... */ }

into

template <typename... Args>
void foo(std::string&& name, Args&&... args) { /* ... */ }

template <typename... Args>
void foo(std::string& name, Args&&... args) { /* ... */ }

as "bar"s is a prvalue and would match your main function since that would deduce a rvalue reference which is preferred to a const lvalue reference.

like image 95
NathanOliver Avatar answered Feb 09 '23 12:02

NathanOliver