我一直以为我理解scala implicits直到最近才遇到奇怪的问题.
在我的应用程序中,我有几个域类
case class Foo(baz: String)
case class Bar(baz: String)
Run Code Online (Sandbox Code Playgroud)
还有一个能够从字符串构造域对象的类.它可以被子类化以进行真正的反序列化并不重要.
class Reads[A] {
def read(s: String): A = throw new Exception("not implemented")
}
Run Code Online (Sandbox Code Playgroud)
接下来,有隐式反序列化器
implicit val fooReads = new Reads[Foo]
implicit val barReads = new Reads[Bar]
Run Code Online (Sandbox Code Playgroud)
以及将字符串转换为域类之一的帮助器
def convert[A](s: String)(implicit reads: Reads[A]): A = reads.read(s)
Run Code Online (Sandbox Code Playgroud)
不幸的是,在尝试使用它时
def f(s: String): Foo = convert(s)
Run Code Online (Sandbox Code Playgroud)
我得到编译错误
error: ambiguous implicit values:
both value fooReads of type => Reads[Foo]
and value barReads of type => Reads[Bar]
match expected type Reads[A]
def f(s: String): …Run Code Online (Sandbox Code Playgroud) 我已经对一些C++代码做了一些重构,并发现了许多我不知道的隐式转换引起的错误.
struct A *a();
bool b() {
return a();
}
void c() {
int64_t const d(b());
}
Run Code Online (Sandbox Code Playgroud)
b,返回类型a静默地转换为bool.c,返回的值b被静默提升为int64_t.如何在原始类型之间隐式转换时收到警告或错误?
-Wconversion似乎只能获得与上述示例无关的几个任意转换.BOOST_STRONG_TYPEDEF 不是一个选项(我的类型需要是POD,因为它们在磁盘结构中使用).这个例子似乎用VC10和gcc编译(虽然我的gcc版本很老).
编辑:R.Martinho Fernandez在gcc 4.7上试过这个并且行为仍然是一样的.
struct Base
{
operator double() const { return 0.0; }
};
struct foo
{
foo(const char* c) {}
};
struct Something : public Base
{
void operator[](const foo& f) {}
};
int main()
{
Something d;
d["32"];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但克朗抱怨道:
test4.cpp:19:6: error: use of overloaded operator '[]' is ambiguous (with operand types 'Something' and 'const char [3]')
d["32"]
~^~~~~
test4.cpp:13:10: note: candidate function
void operator[](const foo& f) {}
^
test4.cpp:19:6: note: built-in candidate operator[](long, const …Run Code Online (Sandbox Code Playgroud) c++ clang visual-c++ overload-resolution implicit-conversion
declare @str_datetime varchar(50)
set @str_datetime='30-04-2012 19:01:45' -- 30th April 2012
declare @dt_datetime datetime
select @dt_datetime=@str_datetime
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误:
消息242,级别16,状态3,行4
将varchar数据类型转换为日期时间数据类型导致超出范围的值.
我的问题是SQL Server如何决定使用哪种格式进行隐式日期时间转换?
我有字符串列表(大小,以字节为单位),我从文件中读取.假设其中一个字符串是2968789218,但是当我将其转换为float时,它变为2.00.
到目前为止这是我的代码:
$string = "2968789218";
$float = (float)$string;
//$float = floatval($string);
//the result is same
// result 2.00
Run Code Online (Sandbox Code Playgroud)
任何人?
问题实际上是编码.我改变文件编码现在没问题:D
在对另一个问题的评论中, Jonathan Wakely回应了我的陈述:
您永远不需要显式移动局部变量函数返回值.这是隐含的举动
- >
...永远不要说永远......如果局部变量与返回类型的类型不同,则需要显式移动,例如
std::unique_ptr<base> f() { auto p = std::make_unique<derived>(); p->foo(); return p; },但如果类型相同,则可能会移动...
所以有时我们可能不得不在返回时移动局部变量.
这个例子
std::unique_ptr<base> f() {
auto p = std::make_unique<derived>();
p->foo();
return p;
}
Run Code Online (Sandbox Code Playgroud)
很好,因为它给出了编译错误
> prog.cpp:10:14: error: cannot convert ‘p’ from type
> ‘std::unique_ptr<derived>’ to type ‘std::unique_ptr<derived>&&’
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有一个很好的机会来检测这一般 - 这是这里的语言规则或unique_ptr ??
使用我的编译器,c是54464(16位截断)并且d是10176.但是gcc,c是120000并且d是600000.
什么是真实的行为?行为是否未定义?或者我的编译器是假的?
unsigned short a = 60000;
unsigned short b = 60000;
unsigned long c = a + b;
unsigned long d = a * 10;
Run Code Online (Sandbox Code Playgroud)
是否可以选择提醒这些案件?
Wconversion警告:
void foo(unsigned long a);
foo(a+b);
Run Code Online (Sandbox Code Playgroud)
但没有警告:
unsigned long c = a + b
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
class A {
public:
operator int() const { return 5; }
};
class B {
public:
operator int() const { return 6; }
};
int main() {
A a;
B b;
int myInt = true ? a : b;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尝试使用Visual Studio 2017 RC编译该代码会导致以下错误:
错误C2446 ::
:没有转换B为A注意:没有可用于执行此转换的用户定义转换运算符,或者无法调用运算符
...这是令人惊讶的,因为在这种情况下,我希望它将它们转换为通用类型int.
clang (4.0)成功编译相同的代码,没有任何错误或警告.
在这种情况下,哪两个是正确的,为什么?
c++ type-conversion ternary implicit-conversion operator-keyword
我想了解为什么eta-expansion(§6.26.5)不适用于重载方法.例如,如果我有以下两种方法:
def d1(a: Int, b: Int) {}
def r[A, B](delegate: (A, B) ? Unit) {}
Run Code Online (Sandbox Code Playgroud)
我可以做这个:
r(d1)
Run Code Online (Sandbox Code Playgroud)
但是,当重载r时它将不再起作用:
def r[A, B](delegate: (A, B) ? Unit) {}
def r[A, B, C](delegate: (A, B, C) ? Unit) {}
r(d1) // no longer compiles
Run Code Online (Sandbox Code Playgroud)
我必须显式地将方法转换为部分应用的函数:
r(d1 _)
Run Code Online (Sandbox Code Playgroud)
有没有办法通过显式转换完成以下操作?
def r[A, B](delegate: (A, B) ? Unit) {}
def r[A, B, C](delegate: (A, B, C) ? Unit) {}
def d1(a: Int, b: Int) {}
def d2(a: Int, b: Int, c: Int) {}
r(d1) …Run Code Online (Sandbox Code Playgroud) 问题:隐式bool转换是否总是回退到尝试隐式转换为void*?(如果存在类型的转换函数).如果是这样,为什么?
考虑以下简短程序:
#include <iostream>
class Foo{
public:
operator void*() const
{
std::cout << "operator void*() const" << std::endl;
return 0;
}
};
int main()
{
Foo f;
if(f)
std::cout << "True" << std::endl;
else
std::cout << "False" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该程序的输出是:
operator void*() const
False
Run Code Online (Sandbox Code Playgroud)
意思是,void*被称为转换函数.如果我们explicit在转换函数前面标记限定符,则隐式转换void*将失败.
编辑:
似乎很多答案是"空指针可以转换为false".我理解这一点,我的问题是关于"如果我不能直接调用operator bool()那么我将尝试转换为任何指针".