如果我有一个功能:
f : A => B => C
Run Code Online (Sandbox Code Playgroud)
我可以定义一个隐式转换,以便在需要函数的地方使用(A, B) => C它.这也是另一个方向.
为什么这些转换不是隐式的(或隐式可用)?我假设坏事可能会发生一些坏事.这有什么价值?
使用Casting null并不能作为灵感编译,并且来自Eric Lippert的评论:
这表明了一个有趣的案例."uint x =(int)0;" 即使int不能隐式转换为uint也会成功.
我们知道这不起作用,因为object无法分配到string:
string x = (object)null;
Run Code Online (Sandbox Code Playgroud)
但这确实如此,但直觉上它不应该:
uint x = (int)0;
Run Code Online (Sandbox Code Playgroud)
为什么不编译器允许这种情况下,int不隐式转换为uint?
.net c# compiler-construction type-conversion implicit-conversion
我可以定义一个接受a的函数 Seq[Char]
def f(s: Seq[Char]) = s
Run Code Online (Sandbox Code Playgroud)
如果我通过一个String:
scala> f("this")
res8: Seq[Char] = this
Run Code Online (Sandbox Code Playgroud)
这意味着我可以在一个map:
scala> List("this").map(s => f(s))
res9: List[Seq[Char]] = List(this)
Run Code Online (Sandbox Code Playgroud)
那我为什么不能这样做呢?:
scala> List("this").map(f)
<console>:10: error: type mismatch;
found : Seq[Char] => Seq[Char]
required: java.lang.String => ?
List("this").map(f)
^
Run Code Online (Sandbox Code Playgroud) 在这个提案中:
N3830 Scoped Resource - 标准库的通用RAII包装器
scoped_resource提出了RAII包装器.
在第4页,有一些代码如下:
Run Code Online (Sandbox Code Playgroud)auto hFile = std::make_scoped_resource( ... ); ... // cast operator makes it seamless to use with other APIs needing a HANDLE ReadFile(hFile, ...);
Win32 API ReadFile()采用原始 HANDLE参数,而不是hFile实例scoped_resource,因此为了使上述代码有效,有一个隐式转换运算符scoped_resource.
但是,避免这种隐性转换不是"现代"建议吗?
例如,ATL/MFC CString具有隐式转换(强制转换操作符)到LPCTSTR(const char/wchar_t*即原始C字符串指针),而STL字符串具有显式 c_str()方法.
类似地,智能指针unique_ptr具有访问底层包装指针的显式 get()方法; 此博客文章中也出现了针对隐式转换的建议:
那么,对于现代C++来说,这些隐式转换(如ATL/MFC CString和新提出的scoped_resource …
考虑以下示例:
#include <stdio.h>
int main(void)
{
unsigned char a = 15; /* one byte */
unsigned short b = 15; /* two bytes */
unsigned int c = 15; /* four bytes */
long x = -a; /* eight bytes */
printf("%ld\n", x);
x = -b;
printf("%ld\n", x);
x = -c;
printf("%ld\n", x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译我正在使用GCC 4.4.7(它没有给我任何警告):
gcc -g -std=c99 -pedantic-errors -Wall -W check.c
Run Code Online (Sandbox Code Playgroud)
我的结果是:
-15
-15
4294967281
Run Code Online (Sandbox Code Playgroud)
问题是为什么两者unsigned char和unsigned short值都正确地"传播"到(签名)long,而unsigned int …
我有一个类,我想轻松写出字符串(例如用于记录目的).我可以使用隐式运算符隐式地将对象强制转换为字符串而不是覆盖ToString方法吗?
例如,我有一个人带班姓名和年龄:
public class Person
{
public string Name { get; set; }
public int Age { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我可以覆盖ToString:
public override string ToString()
{
return String.Format("Name: {0}, Age: {1}", this.Name, this.Age);
}
Run Code Online (Sandbox Code Playgroud)
或者我可以使用隐式运算符:
public static implicit operator string(Person p)
{
return String.Format("Name: {0}, Age: {1}", p.Name, p.Age);
}
Run Code Online (Sandbox Code Playgroud)
现在,将此对象传递给期望字符串的方法,而不是
Log(Person.ToString());
Run Code Online (Sandbox Code Playgroud)
我可以打电话
Log(Person);
Run Code Online (Sandbox Code Playgroud)
我甚至可以在隐式转换中调用重写的ToString
public static implicit operator string(Person p)
{
return p.ToString();
}
Run Code Online (Sandbox Code Playgroud)
这是对String的隐式运算符强制转换的错误用法吗?需要此功能时的最佳做法是什么?我怀疑只是重载ToString将是最佳实践答案,如果是这样,我有几个问题:
为什么一个能投射出std::ostream的void指针?我不知道有任何这样的转换运算符std::ostream.代码如下
#include <iostream>
int main()
{
void *p = std::cout; // why does this work?
}
Run Code Online (Sandbox Code Playgroud)
我问这个问题,因为我已经看到new调用了一个放置操作符
Foo* pFoo = new (std::cerr) Foo;
Run Code Online (Sandbox Code Playgroud)
并且完全不知道为什么会写这样的东西.
PS:我正在使用或不使用g ++ 4.9.2进行编译-std=c++11.clang ++ 不接受代码.
PSS:发现由于所谓的"安全bool问题"(参见@ nicebyte的回答),在预C++ 11 void*中定义了一个转换运算符std::ostream,然后在C++ 11中将其删除.但是,我的代码使用g ++在C++ 11中编译得很好.更重要的是,clang ++拒绝它,无论我使用什么版本的标准,即使有-std=c++98,尽管我的理解是它应该接受,如果编译为pre-C++ 11.
在哪里sqlContext.implicits._定义$"字符串"来表示对父数据帧列的数据帧调用?具体来说,我对看到以下内容感到困惑:
import sqlContext.implicits._
df.where($"type".isin("type1","type2") and $"status".isin("completed","inprogress"))
Run Code Online (Sandbox Code Playgroud) 有问题的结构/类:
public struct HttpMethod
{
public static readonly HttpMethod Get = new HttpMethod("GET");
public static readonly HttpMethod Post = new HttpMethod("POST");
public static readonly HttpMethod Put = new HttpMethod("PUT");
public static readonly HttpMethod Patch = new HttpMethod("PATCH");
public static readonly HttpMethod Delete = new HttpMethod("DELETE");
private string _name;
public HttpMethod(string name)
{
// validation of name
_name = name.ToUpper();
}
public static implicit operator string(HttpMethod method)
{
return method._name;
}
public static implicit operator HttpMethod(string method)
{
return new HttpMethod(method); …Run Code Online (Sandbox Code Playgroud) Clang 6,clang 7和gcc 7.1,7.2和7.3都同意以下是有效的C++ 17代码,但在C++ 14和C++ 11下是不明确的.MSVC 2015和2017也接受它.但是,即使在c ++ 17模式下,gcc-8.1和8.2也拒绝它:
struct Foo
{
explicit Foo(int ptr);
};
template<class T>
struct Bar
{
operator T() const;
template<typename T2>
explicit operator T2() const;
};
Foo foo(Bar<char> x)
{
return (Foo)x;
}
Run Code Online (Sandbox Code Playgroud)
接受它的编译器选择模板显式转换函数,Bar::operator T2().
拒绝它的编译器同意以下两者之间存在歧义:
Bar<char>到char,然后从所述隐式内置转换char到int,然后将显式构造的Foo(INT).那么,哪个编译器是对的?C++ 14和C++ 17之间标准的相关区别是什么?
附录:实际错误消息
这是错误gcc-8.2 -std=c++17.gcc-7.2 -std=c++14打印相同的错误:
<source>: In function 'Foo foo(Bar<char>)':
<source>:17:17: error: call of overloaded 'Foo(Bar<char>&)' …Run Code Online (Sandbox Code Playgroud)