Но мой любимый лефтикус в одном из своих докладов (чет не помню, в каком, но в последние пару лет) поделился синтаксическим трюком, как их запретить.
Вот у нас есть пример.
struct Path {
Path(const std::string& p) : path(p) {}
Path(const char* p) : path(p) {}
std::string path;
};
void f(const Path& path, const std::string& mode) {
std::cout << "Path: " << path.path << std::endl;
std::cout << "Mode: " << mode << std::endl;
}
Мы хотим как-то запускать функцию
f.У нас, казалось бы, есть защита от неправильного порядка аргументов.
f(Path("/etc/tmp"), std::string{"rw"});
// f(std::string{"rw"}, Path("/etc/tmp"));
// error: no matching function for call to 'f'
Но есть проблема. Оба типа могут неявно конструироваться от строки. Вот эти обе строчки сработают:
f("/etc/tmp", "rw");
f("rw", "/etc/tmp");
Есть решение! Нам поможет вот такая конструкция:
```cpp
void f(const auto&, const auto&) = delete;
void f(const Path& path, const std::string& mode) {
std::cout << "Path: " << path.path << std::endl;
std::cout << "Mode: " << mode << std::endl;
}
```
Что мы теперь получим при вызове функций от голых строк?
```
<source>:18:5: error: call to deleted function 'f'
18 | f("/etc/tmp", "rw");
```
Прекрасный трюк, очень мне нравится.