“explicit”关键字对默认构造函数有影响吗?

42

在不带参数的构造函数中使用explicit关键字有什么原因吗?它会产生任何影响吗?我想知道这个问题,因为我刚刚遇到了这行代码。

explicit char_separator()

在文档 boost::char_separator 的页面接近末尾处有提到,但是那里没有进一步的解释。


10
非重复问题;这个问题涉及到explicit关键字的一个非常特定的角落情况。 - Fred Foo
4
那不是函数,那是构造函数 - 请参考https://dev59.com/fXVD5IYBdhLWcg3wAWkO#121163。 - Skizz
很难在没有看到实际示例的情况下进行判断。 - BЈовић
@VJo:请查看<boost/token_functions.hpp>,它在那里。 - Fred Foo
如果我们正在讨论上面链接中描述的char_separator,那么它是一个构造函数,这个问题就是重复的。 - BЈовић
2个回答

16

阅读成员的解释

explicit char_separator(const Char* dropped_delims,
                        const Char* kept_delims = "",
                        empty_token_policy empty_tokens = drop_empty_tokens)
explicit char_separator()
第一个构造函数中的explicit关键字要求显式创建char_separator类型的对象。 What does the explicit keyword mean in C++? 很好地解释了 explicit 关键字。
第二个构造函数中的explicit关键字是噪音,会被忽略。 编辑内容 从 c++ 标准中可得知:
7.1.2 第6段指出:

explicit 指示符仅在类声明中的构造函数声明中使用;请参见12.3.1。

12.3.1 第2段指出:

显式构造函数像非显式构造函数一样构造对象,但只在直接初始化语法(8.5)或强制转换(5.2.9、5.4)明确使用时才这样做。默认构造函数可以是显式构造函数;这种构造函数将用于执行默认初始化或值初始化(8.5)。 [示例:

class Z {
public:
explicit Z();
explicit Z(int);
// ...
};
Z a;               // OK: default-initialization performed
Z a1 = 1;          // error: no implicit conversion
Z a3 = Z(1);       // OK: direct initialization syntax used
Z a2(1);           // OK: direct initialization syntax used
Z* p = new Z(1);   // OK: direct initialization syntax used
Z a4 = (Z)1;       // OK: explicit cast used
Z a5 = static_cast<Z>(1); // OK: explicit cast used

——示例结束]

因此,使用显式关键字的默认构造函数与不使用该关键字的默认构造函数相同。


"第二个构造函数的explicit关键字是一个噪音,会被忽略。" 什么? - Puddle
4
考虑到 C++ 的现代版本中的大括号初始化,此答案是错误的。证明可参考链接:https://godbolt.org/z/zdNvTp(如果移除 explicit 关键字,代码将编译通过)。 - Etienne Dechamps
explicit 影响某些初始化能否被执行。 - smiling_nameless

8

是的,它确实有影响。

比较:

struct A
{
    A() {}
};

void foo(A) {}

int main()
{
    foo({}); // ok
}

并且:

struct A
{
    explicit A() {}
};

void foo(A) {}

int main()
{
    foo({}); // error
}

1
这是正确的答案,从C++11开始。当时我提出问题时,我仍在使用C++03,其中大括号初始化不可用。Boost已经领先一步 :) - Kilian Brendel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接