明确论证?

dar*_*une 4 c++ explicit c++17

explicit可以用于例如。一个构造函数或转换函数,以避免隐式调用该构造函数/转换 - 简而言之。

我想知道是否有可能以某种方式单个参数(缺少滚动新类型)?也许使用编译器扩展?

使用引用使复制构造变得不可能,因此这是一种解决方案,尽管不是我正在寻找的解决方案。有时能够explicit在功能级别强制执行将是简洁的工具/界面说明符。

void f(std::string& s); //cannot copy convert into s

void f(const std::string& t);//calling with char* allowed
Run Code Online (Sandbox Code Playgroud)

特别是对于字符串,应该使用什么类型来避免从char*?

Nat*_*ica 9

您不能显式标记参数,但您可以做的是添加一个具有右值引用参数的重载并将其删除,例如

void f(const std::string& t);
void f(std::string&&) = delete;
Run Code Online (Sandbox Code Playgroud)

这将允许f接受 a std::string,但如果由于隐式转换而创建了右值,则将选择右值引用重载,并且您将收到有关使用已删除函数的编译器错误。

这样做的原因是右值引用参数在重载解析中优于对 const 的引用,因此在传递临时值时将始终调用它。只有在选择函数后,编译器才会看到它被删除,因此它会发出错误。


Bar*_*rry 7

使用 C++20,您可以执行以下操作:

void f(std::same_as<std::string> auto const& s);
Run Code Online (Sandbox Code Playgroud)

使用 C++17,这相当于:

template <typename T,
    std::enable_if_t<std::is_same_v<T, std::string>, int> = 0>
void f(T const& s);
Run Code Online (Sandbox Code Playgroud)

也就是说,我们必须T准确地推断出std::string(哪些字符串文字或其他char指针显然不是)。


请注意,这会拒绝以下类型:

struct D : std::string { };
Run Code Online (Sandbox Code Playgroud)

这也不需要转换。如果您想允许这些,那就是将概念更改为std::derived_fromenable_if使用std::is_convertible_v<T*, std::string*>.