- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这个代码:
class MyString
{
public:
operator const char*() const {
return nullptr;
}
};
class YourString
{
public:
YourString() {}
YourString(const char* ptr) {
(void)ptr;
}
YourString& operator=(const char* ptr)
{
return *this;
}
};
int main()
{
MyString mys;
YourString yoursWorks;
yoursWorks = mys;
YourString yoursAlsoWorks(mys);
YourString yoursBreaks = mys;
}
$ "C:\Program Files\LLVM\msbuild-bin\CL.exe" ..\string_conversion.cpp
..\string_conversion.cpp(32,13): error: no viable conversion from 'MyString' to 'YourString'
YourString yoursBreaks = mys;
^ ~~~
..\string_conversion.cpp(10,7): note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'MyString' to
'const YourString &' for 1st argument
class YourString
^
..\string_conversion.cpp(10,7): note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'MyString' to
'YourString &&' for 1st argument
class YourString
^
..\string_conversion.cpp(14,2): note: candidate constructor not viable: no known conversion from 'MyString' to 'const char *' for 1st argument
YourString(const char* ptr) {
^
..\string_conversion.cpp(5,2): note: candidate function
operator const char*() const {
^
1 error generated.
$ g++.exe -std=gnu++14 ..\string_conversion.cpp
..\string_conversion.cpp: In function 'int main()':
..\string_conversion.cpp:33:27: error: conversion from 'MyString' to non-scalar type 'YourString' requested
YourString yoursBreaks = mys;
^
YourString yoursBreaks = mys;
YourString yoursBreaks(mys);
/Za
flag 导致代码不被接受。
$ "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\CL.exe" /Za ..\string_conversion.cpp
string_conversion.cpp
..\string_conversion.cpp(33): error C2440: 'initializing': cannot convert from 'MyString' to 'YourString'
..\string_conversion.cpp(33): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
最佳答案
tldr;代码格式错误,MSVC 错误地接受它。复制初始化不同于直接初始化。外行的解释是yoursBreaks
的初始化将涉及两次用户定义的转换( MyString --> const char* --> YourString
),而直接初始化涉及一次用户定义的转换( MyString --> const char*
),并且您最多只能进行一次用户定义的转换。强制执行该规则的标准解释是 [over.best.ics] 不允许在通过转换构造函数从不相关的类类型复制初始化类类型的上下文中进行用户定义的转换。
达到标准!有什么作用:
YourString yoursBreaks = mys;
The initialization that occurs in the
=
form of a brace-or-equal-initializer or condition (6.4), as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.6.1), is called copy-initialization.
T var = expr;
尽管出现了
=
,这从不调用
operator=
.我们总是通过构造函数或转换函数。
If the destination type is a (possibly cv-qualified) class type:
— If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, [...]
— Otherwise, if the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, [...]
— Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution (13.3). If the conversion cannot be done or is ambiguous, the initialization is ill-formed.
— The converting constructors (12.3.1) of T are candidate functions.
— When the type of the initializer expression is a class type “cvS
”, the non-explicit conversion functions ofS
and its base classes are considered. When initializing a temporary to be bound to the first parameter of a constructor where the parameter is of type “reference to possibly cv-qualifiedT
” and the constructor is called with a single argument in the context of direct-initialization of an object of type “cv2T
”, explicit conversion functions are also considered. Those that are not hidden withinS
and yield a type whose cv-unqualified version is the same type asT
or is a derived class thereof are candidate functions. Conversion functions that return “reference toX
” return lvalues or xvalues, depending on the type of reference, of typeX
and are therefore considered to yieldX
for this process of selecting candidate functions.
YourString
的转换构造函数, 哪个是:
YourString(const char* );
MyString
没有返回
YourString
的转换函数或从它派生的类类型。
Then the best viable function is selected based on the implicit conversion sequences (13.3.3.1) needed to match each argument to the corresponding parameter of each viable function.
A well-formed implicit conversion sequence is one of the following forms:
— a standard conversion sequence (13.3.3.1.1),
— a user-defined conversion sequence (13.3.3.1.2), or
— an ellipsis conversion sequence (13.3.3.1.3).However, if the target is
— the first parameter of a constructor or
— the implicit object parameter of a user-defined conversion functionand the constructor or user-defined conversion function is a candidate by
— 13.3.1.3, when the argument is the temporary in the second step of a class copy-initialization,
— 13.3.1.4, 13.3.1.5, or 13.3.1.6 (in all cases), or
— the second phase of 13.3.1.7 [...]
user-defined conversion sequences are not considered. [ Note: These rules prevent more than one user-defined conversion from being applied during overload resolution, thereby avoiding infinite recursion. —end note ] [ Example:struct Y { Y(int); };
struct A { operator int(); };
Y y1 = A(); // error: A::operator int() is not a candidate
struct X { };
struct B { operator X(); };
B b;
X x({b}); // error: B::operator X() is not a candidate—end example ]
MyString
的转换序列至
const char*
,在这种情况下不考虑,所以这个构造函数是不可行的。
YourString yoursAlsoWorks(mys);
The applicable constructors are enumerated (13.3.1.3), and the best one is chosen through overload resolution (13.3). The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s). If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.
For direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate functions are all the constructors of the class of the object being initialized.
YourString(const char* ) // yours
YourString(YourString const& ) // implicit
YourString(YourString&& ) // implicit
YourString(const char*)
,很简单,
MyString
有一个可行的转换函数至
const char*
,所以它被使用了。
MyString --> const char*
.一次转换没问题。
关于c++ - 哪些规则控制在类型之间使用多个用户定义的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41594186/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!