Option可以隐式转换为Iterable- 但为什么它不只是直接实现Iterable:
def iterator = new Iterator[A] {
var end = !isDefined
def next() = {
val n = if (end) throw new NoSuchElementException() else get
end = true
n
}
def hasNext = !end
}
Run Code Online (Sandbox Code Playgroud)
编辑: 事实上它甚至比那更糟糕,因为在2.8 Option中声明了一个iterator方法:
def iterator: Iterator[A] =
if (isEmpty) Iterator.empty else Iterator.single(this.get)
Run Code Online (Sandbox Code Playgroud) 作为练习,我尝试创建一个隐式转换,它将接受一个函数并生成一个Runnable.这样你就可以调用接受Runnable对象的Java方法,并像封闭一样使用它们.
隐式转换很容易:
implicit def funToRunnable(fun : Unit) = new Runnable() { def run = fun }
Run Code Online (Sandbox Code Playgroud)
但是我不知道怎么称呼它.如何传入一个返回Unit的无参数函数,而不是立即进行评估?例如,我想要以下内容来打印"12",而是打印"21"因为print("2")一次评估.
var savedFun : Runnable = null
def save(r : Runnable) = { savedFun = r }
save(print("2"))
print("1")
savedFun.run()
Run Code Online (Sandbox Code Playgroud)
如何告诉编译器将其print("2")视为函数的主体,而不是立即进行评估?我试过的一些可能性,比如
save(() => print("2"))
Run Code Online (Sandbox Code Playgroud)
要么
save(=> print("2"))
Run Code Online (Sandbox Code Playgroud)
不是合法的语法.
假设我有一些类型的对象T,我想把它放到一个引用包装器中:
int a = 5, b = 7;
std::reference_wrapper<int> p(a), q(b); // or "auto p = std::ref(a)"
Run Code Online (Sandbox Code Playgroud)
现在我可以很容易地说if (p < q),因为引用包装器已转换为其包装类型.一切都很开心,我可以处理一组参考包装器,就像它们是原始对象一样.
(正如下面链接的问题所示,这可以是生成现有集合的备用视图的有用方法,可以随意重新排列,而不会产生完整副本的成本,以及维护原始集合的更新完整性. )
但是,对于某些类,这不起作用:
std::string s1 = "hello", s2 = "world";
std::reference_wrapper<std::string> t1(s1), t2(s2);
return t1 < t2; // ERROR
Run Code Online (Sandbox Code Playgroud)
我的解决方法是在这个答案中定义一个谓词*; 但我的问题是:
为什么以及何时可以将运算符应用于引用包装器并透明地使用包装类型的运算符?为什么会失败std::string?它与std::string模板实例的事实有什么关系?
*)更新:根据答案,似乎使用std::less<T>()是一般解决方案.
c++ templates implicit-conversion reference-wrapper template-argument-deduction
我想了解为什么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) 使用以下代码可以清楚地解决该问题:
#include <functional>
#include <iostream>
#include <vector>
int main() {
//std::vector<int> a, b;
int a = 0, b = 0;
auto refa = std::ref(a);
auto refb = std::ref(b);
std::cout << (refa < refb) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用注释std::vector<int> a, b;而不是int a = 0, b = 0;,则代码不会在GCC 5.1,clang 3.6或MSVC'13中的任何一个上编译.在我看来,std::reference_wrapper<std::vector<int>>可以隐式转换std::vector<int>&为LessThanComparable,因此它应该是LessThanComparable本身.有人可以向我解释一下吗?
c++ language-lawyer implicit-conversion c++11 reference-wrapper
问题:隐式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()那么我将尝试转换为任何指针".
令人惊讶的是,无论在函数名之前使用什么符号,以下代码在 gcc 和 clang 中都能很好地编译:*,&或者什么都不用。标准是否允许其中任何一个?存储函数指针的首选方法是什么?
#include <stdio.h>
typedef int foo(int a);
template <typename X>
int g(int y) {
return y * sizeof(X);
}
int main() {
foo* xxx;
// 1. what is correct according to standard?
// 2. why they all work?
xxx = *g<float>;
xxx = &g<float>;
xxx = g<float>;
printf("ok %d\n", xxx(5));
}
Run Code Online (Sandbox Code Playgroud) 我有一个ruby脚本,它将通过从另一个文件中获取和合并值来创建两个文件.
#Resources
require 'rubygems'
require 'csv'
col_date = []
col_constant1 = []
col_constant2 = []
col_appYear = []
col_statsDesc = []
col_keyStats =[]
col_weeklyTotal=[]
weekly_total = []
fname = "finalStats.csv" #variable for capture file
finalStatsFile = File.open(fname, "w") #write to capture file
fname2 = "weeklyStats.csv"
weeklyStatsFile = File.open(fname2, "w")
CSV.foreach('compareData.csv', converters: :numeric) do |row|
weekly_total << row[0] - row[1]
weekly_total.each do |data|
data << weekly_total.shift
weeklyStatsFile.puts data
end
end
#retrieve stats from original document
CSV.foreach("autoCapture.csv") {|row| col_date << row[0]}
CSV.foreach("autoCapture.csv") …Run Code Online (Sandbox Code Playgroud) 我想定义从(特定)lambda表达式到用户定义类型的隐式转换.我尝试了以下方法:
public static implicit operator DualElement<T>(Func<OPTatom, OPTatom, T> atomMap)
{
return new DualElement<T>(e => atomMap(e[0],e[1]));
}
Run Code Online (Sandbox Code Playgroud)
然后我试了一下
DualElement<double> dubidu = (i, j) => cost[i, j];
Run Code Online (Sandbox Code Playgroud)
它给出了"无法转换lambda表达式...因为它不是委托类型"
相反,有效的是:
DualElement<double> dideldu = (Func<OPTatom, OPTatom, double>)((i, j) => cost[i, j]);
Run Code Online (Sandbox Code Playgroud)
我猜,lambda表达式没有'Func'类型,所以我必须在隐式转换中加入不同的东西.
有人可以给我一个暗示吗?
考虑以下课程:
struct C
{
/* Class contents, without any arithmetic operator... */
constexpr operator int() noexcept; // Implicit conversion to int
};
Run Code Online (Sandbox Code Playgroud)
我的问题是:
std::sort当前使用默认<运算符的标准算法?LessThanComparable概念吗?LessThanComparable.c++ ×5
scala ×3
c# ×1
c++-concepts ×1
c++11 ×1
c++17 ×1
function ×1
lambda ×1
methods ×1
ruby ×1
runnable ×1
scala-option ×1
template-argument-deduction ×1
templates ×1