重载解决方案:显式和初始化语法的作用是什么?
Overload Resolution: What is the role of explicit and the initialization syntax?
假设我有一个不可变的 String
class 如下:
#include <iostream>
#include <string>
class String
{
public:
explicit String(const char *Value) : Size(std::strlen(Value)), Value(new char[Size + 1])
{
std::memcpy(this->Value, Value, Size + 1);
std::cout << Value << ", novice." << Size << std::endl;
}
template <typename T, std::size_t N> String(const T (&Value)[N]) : Size(N - 1), Value(new char[N])
{
std::memcpy(this->Value, Value, N);
std::cout << Value << ", expert." << Size << std::endl;
}
~String()
{
delete[] Value;
}
private:
const std::size_t Size;
char *Value;
};
void main()
{
auto &s = "Welcome to C++";
String string = s;
String str {s};
String st(s);
return;
}
我想知道 explicit
所起的作用以及在选择构造函数重载时初始化语法有何不同。
我知道对于 str
和 st
,我明确地调用了带有指向 const char
的指针的构造函数,因此它们打印出:
Welcome to C++, novice.
Welcome to C++, novice.
但我不明白为什么 string
Welcome to C++, expert.
打印出来了。请说明如何选择过载。
有
String str {s};
String st(s);
explicit String(const char *Value)
之所以选择指针重载是因为它不是模板化的。指针和数组构造函数都被认为与 s
完全匹配,因此这会产生歧义,但由于数组构造函数是一个模板,因此它被认为不如指针构造函数匹配。即使您删除了 explicit
,仍会选择指针重载。
现在
String string = s;
explicit
确实重要,因为 s
不是 String
。这意味着编译器需要将其隐式转换为一个,以便它选择数组构造函数,因为它是完全匹配的,并且是唯一可行的构造函数,因为显式构造函数不能用于隐式转换。
假设我有一个不可变的 String
class 如下:
#include <iostream>
#include <string>
class String
{
public:
explicit String(const char *Value) : Size(std::strlen(Value)), Value(new char[Size + 1])
{
std::memcpy(this->Value, Value, Size + 1);
std::cout << Value << ", novice." << Size << std::endl;
}
template <typename T, std::size_t N> String(const T (&Value)[N]) : Size(N - 1), Value(new char[N])
{
std::memcpy(this->Value, Value, N);
std::cout << Value << ", expert." << Size << std::endl;
}
~String()
{
delete[] Value;
}
private:
const std::size_t Size;
char *Value;
};
void main()
{
auto &s = "Welcome to C++";
String string = s;
String str {s};
String st(s);
return;
}
我想知道 explicit
所起的作用以及在选择构造函数重载时初始化语法有何不同。
我知道对于 str
和 st
,我明确地调用了带有指向 const char
的指针的构造函数,因此它们打印出:
Welcome to C++, novice.
Welcome to C++, novice.
但我不明白为什么 string
Welcome to C++, expert.
打印出来了。请说明如何选择过载。
有
String str {s};
String st(s);
explicit String(const char *Value)
之所以选择指针重载是因为它不是模板化的。指针和数组构造函数都被认为与 s
完全匹配,因此这会产生歧义,但由于数组构造函数是一个模板,因此它被认为不如指针构造函数匹配。即使您删除了 explicit
,仍会选择指针重载。
现在
String string = s;
explicit
确实重要,因为 s
不是 String
。这意味着编译器需要将其隐式转换为一个,以便它选择数组构造函数,因为它是完全匹配的,并且是唯一可行的构造函数,因为显式构造函数不能用于隐式转换。