V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  geelaw  ›  全部回复第 14 页 / 共 172 页
回复总数  3435
1 ... 10  11  12  13  14  15  16  17  18  19 ... 172  
什么叫做开通 cash ?

很多美国的银行都参与了 Zelle ,你开好账户自然就有了,所以问题归结为如何开美国的往来账户。
270 天前
回复了 LuckyPocketWatch 创建的主题 C++ c++如何判断二进制相同的对象?
@geelaw 最后一段里面第一个例子是错误的,因为数组是 implicit-lifetime object ,于是在 a == b 执行的时候它的效果已经变成了 [expr.eq]/3.2 了。不过第二个例子 p == p 依然成立。
270 天前
回复了 LuckyPocketWatch 创建的主题 C++ c++如何判断二进制相同的对象?
@geelaw #28 贴代码无意义是指贴编译之后的机器代码无意义,因为未定义行为包括任何行为,不能根据实现推断标准。
270 天前
回复了 LuckyPocketWatch 创建的主题 C++ c++如何判断二进制相同的对象?
@dangyuluo #13 贴代码无意义,不过您说得对,我需要修正 #10 #11 的说法,因为

根据 [basic.compound]/3 ,指向对象的指针的值“表示的地址”是该对象(若该对象不在其生命周期内,则是该对象曾经、将要)占有的存储的第一个字节。这表示 placement new 返回和传入的指针虽然可能指向了不同的对象,但是它们“表示的地址”相同。

根据 [expr.eq]/3.2 ,两个同类型、指向对象的、不是指向末尾之后的指针相等,如果它们“表示的地址”相等。

#10 里面建议的 std::launder 不必要,并且 #11 里面认为的未定义行为不成立。

---

回到 @dangyuluo #12 我认为应该尽量按照楼主希望的意思自动更正他的代码,所以应该认为

struct A { }; struct B : A { };

并且 new B() 改写为 new (ptr) B()。

---

@sloknyyz #23 @antonius #24 @jujusama #26 指针比较并不是比较数值,考虑

alignas(C) std::byte storage[2 * sizeof(C)];
C *a = new (storage) C() + 1;
C *b = new (storage + sizeof(C)) C();
/* 此时 a 和 b 必然表示相同的地址 */
a == b ? 1 : 2; /* 结果可以是 2 见 [basic.compound]/3 的 note 和 [expr.eq]/3.1 */

再比如

void *p = std::malloc(1);
std::free(p);
p == p ? 1 : 2; /* 结果可以是 2 见 [basic.stc]/4 */
270 天前
回复了 LuckyPocketWatch 创建的主题 C++ c++如何判断二进制相同的对象?
@geelaw #10 原来的问题:C++ 如何判断 ptr == objectA 这段代码的?

既然是未定义行为,编译器可以选择格式化你的硬盘,但大多数编译器并不会这样做。
在我转写的第一段代码里,比较可能发生的有两种:

1. 无事发生,直接进行数值的比较,因此 true 分支会运行。
2. 编译器意识到
(i) ptr 赋值获得的是新对象
(ii) objectA 在 ptr 赋值之后就没有再赋值过
于是意识到 objectA 和 ptr 在标准看来不可能同时有效地指向同一个对象,因此直接删除 if 的 true 分支,导致 true 分支不执行。
270 天前
回复了 LuckyPocketWatch 创建的主题 C++ c++如何判断二进制相同的对象?
假设你的代码是

A *ptr = new A();
A *objectA = ptr;
ptr->~A();
ptr = new (ptr) B(); // 注意这里需要用 placement new
if (ptr == objectA) ptr->doSomething();

并且 B 是 A 的派生类,并且假设 struct B : A { /* 没有额外的成员 */ };

第一,我不知道 new (ptr) B() 是否是未定义行为,这需要翻阅标准。(适合于 A 的 storage 一定适合于 B 吗?)

第二,接下来比较 ptr 和 objectA 绝对是 undefined behavior ,因为 objectA 最后一次赋值的时候指向的对象已经不存在了,所以 objectA 不是有效的指针——这件事情和原来的 storage 上面现在有没有 B 类型的对象、B 是不是 A 的子类没有任何关系。

让我来写一个正确的版本:

char alignas(B) storage[sizeof(B)];
A *ptr = new (storage) A();
A *objectA = ptr;

ptr->~A();
ptr = new (ptr) B();

objectA = std::launder(objectA); // 这一步非常重要

if (objectA == ptr) ptr->doSomething(); /* if 的 true 分支会运行 */
271 天前
回复了 zhishixiang 创建的主题 站长 谷歌域名已经快要无了
Google 的操作很迷惑,5.13 宣布了新 tld ,6.15 宣布了出售业务。
@Myprajna #4 应该说是 Windows 95 而不是 Windows 2000 。

另外那个旧风格的打开文件对话框是因为 ODBC 驱动规定的是 Windows 3.1 风格对话框的钩子,如果该用新版则会导致许多过去的数据库程序无法运行。当然图标换一换还是可以的。
272 天前
回复了 Attenton 创建的主题 C++ c++的单线程 mutex 问题
272 天前
回复了 Attenton 创建的主题 C++ c++的单线程 mutex 问题
272 天前
回复了 Attenton 创建的主题 C++ c++的单线程 mutex 问题
n4849 § 32.5.3.2 没有定义 std::mutex 重入的情况,并且 § 32.5.3.2.1 提示

A program can deadlock if the thread that owns a mutex object calls lock() on that object. If the implementation can detect the deadlock, a resource_deadlock_would_occur error condition might be observed.

没有说必须死锁或者抛出异常。令 std::mutex 和 std::recursive_mutex 是一样的效果,是符合标准的。
273 天前
回复了 hez2010 创建的主题 程序员 给 .NET 实现了 Const Generics
@hez2010 #29 那结论是如果希望用旧方法指定泛型参数的话就要在编译到原生代码的时候提前把类型建立出来,类似于用 rd.xml 设置所有可能需要的值的方式。
273 天前
回复了 hez2010 创建的主题 程序员 给 .NET 实现了 Const Generics
@hez2010 #27 第一个场景确实(这个类似于匿名类型的情况),但我没有理解第二个场景(反射 const generics )。

如果用反射为新的 T 调用 class G1<T> where T : struct { } 当然要现场生成代码。
用反射为新的 int 值调用 class G2<int t> { } 也需要现场生成新代码对不对?
理论解决方案是 verifiable computation 。

实际解决方案是相信或者不用。
275 天前
回复了 hez2010 创建的主题 程序员 给 .NET 实现了 Const Generics
一个小问题:此前我实现这种泛型的时候,都是直接把所有的常量都塞到一个 struct 里面,现阶段的 JIT 编译器不能成功优化吗?

public interface IConstants
{
public int V { get; }
}

public class G<T> where T : IConstants
{
public static void Run() { Console.WriteLine(default(T).V); }
}

public static class Program
{
struct C : IConstants { int IConstants.V { get { return 1; } } }
public static void Main() { G<C>.Run(); }
}

我感觉最简单的实现方式是把 const generics 弄成语法糖……?
276 天前
回复了 iqoo 创建的主题 程序员 关于 C++ 模板一个问题
针对追加的具体问题

struct Base { void print() { } };
struct Str : Base { Str(char const *s) { } };
struct Num : Base { Num(int v) { } };

Base log_deduce(Base obj) { return obj; }
Str log_deduce(Str obj) { return obj; }
Str log_deduce(char const *s) { return s; }
Num log_deduce(Num obj) { return obj; }
Num log_deduce(int v) { return v; }

template <typename... T>
void log_impl(T... args)
{
/* fold expression from C++17 */
((void)(args.print()), ...);
}

template <typename... T>
void log(T... args)
{
log_impl(log_deduce(args)...);
}

int main()
{
log("hello");
log(123);
log(123, "hello");
}

但我感觉楼主的提供的例子离真实用例很远。
276 天前
回复了 iqoo 创建的主题 程序员 关于 C++ 模板一个问题
楼主的代码明明是 log 可以接受任何可以 .print 的类型。提的需求也非常不明确。

你希望模板自动推断存在可以构造的 Base 的子类 T ,还是希望 T 就是参数本身的类型,然后 obj.print 改写为 T1{obj}.print(),其中 T1 是 Base 的某个子类并且可以被 obj 所构造?

另外,建议想清楚自己的问题,如果不是适合用模板解决的问题的话,会从一个小问题,变成一个报错非常长的问题。
1 ... 10  11  12  13  14  15  16  17  18  19 ... 172  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3484 人在线   最高记录 6547   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 44ms · UTC 11:58 · PVG 19:58 · LAX 04:58 · JFK 07:58
Developed with CodeLauncher
♥ Do have faith in what you're doing.