6.1节隐式转换因此定义了身份转换:
身份转换从任何类型转换为相同类型.存在这种转换,使得已经具有所需类型的实体可以说可转换为该类型.
现在,这些句子的目的是什么?
(在§6.1.6隐式参考转换中)
隐式引用转换是:
- [...]
- 从任何引用类型到引用类型,
T如果它具有隐式标识或引用转换为引用类型T0和T0具有标识转换为T.
和:
(在§6.1.7拳击转换中)
- 如果值类型具有
I到接口类型I0的装箱转换并且I0具有到的标识转换,则值类型具有到接口类型的装箱转换I.
最初它们似乎是多余的(同义词).但他们必须出于某种目的,所以为什么他们在那里?
你能给两种类型的例子T1,T2,使得T1将不会是隐式转换为T2,如果不是因为上面引述的段落?
c# language-features language-specifications implicit-conversion
任何人都可以通过Scala隐式转换机制向我解释以下情况.有一个代码:
object Main {
implicit val x:Int => String = v => "val"
implicit def y(v:Int) = "def"
def p(s:String) = print(s)
def main(args: Array[String]): Unit = {
p(1)
}
}
Run Code Online (Sandbox Code Playgroud)
此代码打印"val".但是当我评论第二行时:
//implicit val x:Int => String = v => "val"
Run Code Online (Sandbox Code Playgroud)
代码打印"def".
因此,在这种情况下,隐式转换(x和y)都是可能的.存在非歧义规则 - 只有在没有其他可能的插入转换时才会插入隐式转换.根据这条规则,这段代码根本不应该编译.但代码已成功编译和执行.我不明白的是什么?
谢谢.
是否有一个隐式方法将scala.collection.mutable.StringBuilder转换为java.lang.StringBuilder?
我正在使用一个Java库(JCommander),其中一个方法(usage)接受一个java.jang.StringBuilder参数.
我试图vector使用负索引索引a .所述vector::at()成员函数检查指定索引是否是向量的边界内,并且如果这种情况不会发生,一个out_of_range则抛出异常.
vector<float> array; // sample vector
array.push_back(0.123);
array.push_back(1.234);
array.push_back(2.345);
array.push_back(3.456);
array.push_back(4.567);
int index = -1;
float f = array.at(index);
cout << f << endl;
Run Code Online (Sandbox Code Playgroud)
vector::at()成员函数的签名要求指定的参数是vector<T>::size_type类型,并且此类型unsigned int用于向量,因此编译器应执行从int(index变量的类型)到的隐式转换unsigned int.由于index值是-1在上述例子中,隐式转换index是4294967295(即所述的最大值unsigned int型):此值被传递给vector::at()成员函数,其抛出out_of_range异常.
换句话说,没有引发这种异常,因为vector::at()成员函数看到的是,index小于零,而是由于隐式转换index比的当前大小更大vector.这是正确的解释吗?
在C++中,可以在类或结构中添加隐式转换运算符.例如,3D矢量类型通常包括以下内容:
struct Vector {
float x, y, z;
operator float * () { return reinterpret_cast<float *>(this); }
};
Run Code Online (Sandbox Code Playgroud)
允许使用下标访问向量的元素,传递给需要指针等的函数.我想知道:我们可以编写一个转换运算符来返回对float数组的引用,而不是指向float的指针吗?
(这纯粹是学术上的兴趣.我不知道对于一个简单的指针,引用数组会有什么好处,如果有的话.)
作为一个免费功能,我们可以这样做:
float (&convert(Vector & v))[3]
{
return reinterpret_cast<float(&)[3]>(v);
}
Vector v;
convert(v);
Run Code Online (Sandbox Code Playgroud)
但是,我无法找到正确的语法来执行此操作作为转换运算符.我尝试过这样的事情:
operator float(&)[3] ()
operator float(&())[3]
float (&operator())[3]
Run Code Online (Sandbox Code Playgroud)
和其他各种排列,但我只是得到各种语法错误(g ++ 4.8.1).
是否可以编写一个转换运算符,返回对数组的引用,如果是,那么这样做的语法是什么?
我猜(某些)隐式转换在传递非类型模板参数时适用.例如,应该有从一个转换int到std::size_t用于表达喜欢std::array<int, 7>.但是,请考虑以下代码:
template <bool>
void f() {
std::cout << "false\n";
}
template <>
void f<true>() {
std::cout << "true\n";
}
int main() {
f<1>();
f<4>();
f<0>();
}
Run Code Online (Sandbox Code Playgroud)
我希望int隐式转换到bool这里.但VC,GCC和clang的行为不同.
在VC, ,true,false和false打印,这实在是怪我.
在海湾合作委员会,true,true,和false印,这是我的期望.
在clang上,由于语句,代码根本不编译f<4>();.
候选模板被忽略:第一个模板参数的显式指定参数无效
那么,标准对此有何看法?非类型模板参数的隐式转换规则是什么?
c++ templates type-conversion template-specialization implicit-conversion
今天我在我的程序中输了一个小错误,并且为什么我没有得到任何输出而徘徊,尽管程序编译得很好.基本上它减少到这个:
#include <iostream>
int main()
{
std::cout < "test"; // no << but <
}
Run Code Online (Sandbox Code Playgroud)
我完全不知道在这里执行了什么样的隐式转换,所以程序仍然编译(g ++ 4.9.2甚至g ++ 5).我刚刚意识到clang ++拒绝代码.是否有转换为void*执行(不能想到其他任何东西)?我记得看过这样的东西,但我认为它是用g ++ 5解决的,但似乎并非如此.
编辑:我不与编译-std=c++11,所以代码是有效的在预C++ 11(由于转换到void*的ostream).当用-std=c++11g ++ 5 编译时拒绝代码,g ++ 4.9仍然接受它.
我已经编写了一些隐式代码,如下所示,我想知道为什么i2d不调用函数隐式对话.
object Test {
implicit def i2d(x: Int): Double = {
println("foo")
x.toDouble
}
implicit def d2i(x: Double): Int = {
x.toInt
}
val x: Int = 10
val y: Double = x
val z: Int = 3.5
}
Run Code Online (Sandbox Code Playgroud)
该输出的scalac -Xprint:typer Test.scala
// Test.scala
[[syntax trees at end of typer]]
package <empty> {
object Test extends scala.AnyRef {
def <init>(): Test.type = {
Test.super.<init>();
()
};
implicit def i2d(x: Int): Double = {
scala.this.Predef.println("foo");
x.toDouble …Run Code Online (Sandbox Code Playgroud) 我试图理解为什么一个隐式转换在一个案例中起作用,而在另一个案例中却没有.这是一个例子:
case class Wrapper[T](wrapped: T)
trait Wrapping { implicit def wrapIt[T](x: Option[T]) = x.map(Wrapper(_))
class NotWorking extends Wrapping { def foo: Option[Wrapper[String]] = Some("foo") }
class Working extends Wrapping {
def foo: Option[Wrapper[String]] = {
val why = Some("foo")
why
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我有从隐式转换Option[T]到Option[Wrapper[T]],并正在试图定义一个函数,该函数返回一个可选的字符串,是被隐式包装.
问题是,当我尝试Option[String]直接返回(NotWorking上面)时,我得到一个错误(found : String("foo") required: Wrapper[String]),如果我在返回之前将结果分配给val,那就会消失.
是什么赋予了?
有一种情况,我想收集 JSON 中一个键的路径的所有节点名称。考虑条件:JSON 数组索引“0”、“1”也是允许的,但是很容易忘记引号,这会导致在取消引用时崩溃。所以我希望编译器拒绝这种参数。例子:
#include <vector>
#include <iostream>
int func(const std::vector<const char*>& pin) {
return pin.size();
}
int main() {
// {"aname", "3", "path", "0"} wanted but this still compile
std::cout << func({"aname", "3", "path", 0}) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
参考如何避免对非构造函数进行隐式转换?我尝试了以下内容:
#include <vector>
#include <iostream>
int func(const std::vector<const char*>& pin) {
return pin.size();
}
int func(const std::vector<int>& pin) = delete;
// or
/* I want to describe only pointer type parameter is allowed as element,
but parameter of any …Run Code Online (Sandbox Code Playgroud)