【问题标题】:Why does the keyword `explicit` not apply to function parameters?为什么关键字 `explicit` 不适用于函数参数?
【发布时间】:2014-03-02 04:48:22
【问题描述】:

在某些情况下,可能不需要隐式类型转换。

例如:

#include <string>

using namespace std;

void f(bool)
{}

void f(string)
{}

int main()
{
    auto p = "hello";
    f(p); // Oops!!! Call void f(bool); rather than void f(string);
}

如果C++标准支持关键字explicit可以用来限定函数参数,代码可以修改如下:

#include <string>

using namespace std;

void f(explicit bool) // Illegal in current C++11 standard!
{}

void f(string)
{}

int main()
{
    auto p = "hello";
    f(p); // Call void f(string);

    bool b = true;
    f(b); // Call void f(bool);

    f(8); // Error!
}

为什么 C++ 标准不支持这么方便的功能?

【问题讨论】:

  • 我不关注。 const char*std::string 更适合 bool。前者是一个微不足道的结构,后者不是。所以你要解决的问题是..?
  • 这种情况下,我不想将const char*隐式转换为bool,怎么办?换句话说,如果我愿意,如何在传递参数时禁用隐式类型转换?
  • 所以您不希望隐式转换为布尔值,但您确实希望它隐式转换为std::string?这就是症结所在?
  • @xmllmx 如果人们经常遇到这个问题,并且现有的解决方法不够令人满意,那么它可能有合理的机会被投票加入标准。但我认为情况并非如此,“优雅”并不是为标准已经超过 1300 页的语言添加更多功能的好理由。
  • IMO,想要这是一个很好的迹象,表明您正在不恰当地使用函数重载。 f 做了什么,让它以 boolstring 作为其参数,并以任一方式执行逻辑等效处理是有意义的?

标签: c++ c++11 type-conversion standards overloading


【解决方案1】:
#include <string>
#include <type_traits>      // std::is_same
#include <utility>          // std::enable_if
using namespace std;

template< class Value >
struct Explicit_
{
    Value    value;

    operator Value() const { return value; }

    template<
        class Arg,
        class Enabled = typename enable_if< is_same< Arg, Value >::value, void >::type
        >
    Explicit_( Arg const v ): value( v ) {}
};

void f( Explicit_<bool> ) // Valid in current C++11 standard!
{}

void f( string )
{}

int main()
{
    auto p = "hello";
    f(p); // Call void f(string);

    bool b = true;
    f(b); // Call void f(bool);

    f(8); // Error!
}

【讨论】:

  • 我知道这种技术,但我认为这种技术有一个缺点:考虑 Explicit_,如果类 T 的复制成本很高,那么就会发生双重复制。而且我觉得void f(explicit bool)更有表现力,应该是标准直接支持的。
  • @xmllmx:如果担心复制成本,那就简单地避免复制。 ;-) 也就是说,包装一个引用而不是一个值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
相关资源
最近更新 更多