我有以下JSON
{"a":1, "b":2, "?":1, "??":1}
Run Code Online (Sandbox Code Playgroud)
我知道它有"a"和"b"字段,但我不知道其他字段的名称.所以我想以下列类型解组它:
type Foo struct {
// Known fields
A int `json:"a"`
B int `json:"b"`
// Unknown fields
X map[string]interface{} `json:???` // Rest of the fields should go here.
}
Run Code Online (Sandbox Code Playgroud)
我怎么做?
使用CRTP有时我会编写如下代码:
// this was written first
struct Foo : Base<Foo, ...>
{
...
};
// this was copy-pasted from Foo some days later
struct Bar : Base<Foo, ...>
{
...
};
Run Code Online (Sandbox Code Playgroud)
并且很难理解出现了什么问题,直到我在调试器中跟踪代码并看到Bar的成员未被使用Base.
如何在编译时显示此错误?
(我使用MSVC2010,所以我可以使用一些C++ 0x功能和MSVC语言扩展)
如果接口只有一个方法,我应该使用函数类型吗?
以下是两种方法的示例:
type Delegate interface { | type Delegate func(x int) int
Do(x int) int |
} |
|
type App struct { | type App struct {
delegate Delegate | delegate Delegate
} | }
|
func (this *App) foo() { | func (this *App) foo() {
... | ...
y := this.delegate.Do(x) | y := this.delegate(x)
... | ...
} | }
|
func main() { | func main() {
delegate := &DelegateImpl{} | delegate := &DelegateImpl{}
app …Run Code Online (Sandbox Code Playgroud) 以下是典型的实现type_info::operator==:
#if _PLATFORM_SUPPORTS_UNIQUE_TYPEINFO
bool operator==(const type_info& __rhs) const {
return __mangled_name == __rhs.__mangled_name;
}
#else
bool operator==(const type_info& __rhs) const {
return __mangled_name == __rhs.__mangled_name ||
strcmp(__mangled_name, __rhs.__mangled_name) == 0;
}
#endif
Run Code Online (Sandbox Code Playgroud)
在libstdc ++中它受控制__GXX_MERGED_TYPEINFO_NAMES,
在libc ++中_LIBCPP_NONUNIQUE_RTTI_BIT,
MSVC总是比较字符串.
什么是不比较字符串的平台?
根据这个最新的C++ TS:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4628.pdf,基于对C#async/await语言支持的理解,我是想知道什么是C++协同程序的"执行上下文"(从C#借来的术语)?
我在Visual C++ 2017 RC中的简单测试代码表明,协同程序似乎总是在线程池线程上执行,并且很少控制应用程序开发人员可以执行协同程序的线程上下文 - 例如,应用程序是否可以强制执行所有协同程序(用编译器生成的状态机代码)只在主线程上执行,而不涉及任何线程池线程?
在C#中,SynchronizationContext是一种指定"上下文"的方法,其中所有协程"一半"(编译器生成的状态机代码)将被发布并执行,如以下文章所示:https://blogs.msdn.microsoft.com/pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps /,而Visual C++ 2017 RC中的当前协程实现似乎总是依赖于并发运行时,它默认执行生成的状态机代码线程池线程.是否有类似的同步上下文概念,用户应用程序可以使用它来将协同程序执行绑定到特定的线程?
另外,在Visual C++ 2017 RC中实现的协同程序的当前默认"调度程序"行为是什么?即1)如何准确指定等待条件?2)当满足等待条件时,谁调用暂停的协程的"下半部分"?
关于C#中任务调度的我(天真)猜测是C#"完全"通过任务继续"实现"等待条件 - 等待条件由TaskCompletionSource拥有的任务合成,并且任何需要等待的代码逻辑将被链接为继续因此,如果满足等待条件,例如,如果从低级网络处理程序接收到完整消息,则它执行TaskCompletionSource.SetValue,它将基础任务转换为已完成状态,从而有效地允许链式连续逻辑开始执行(将任务从先前创建的状态置于就绪状态/列表中) - 在C++协程中,我推测std :: future和std :: promise将被用作类似的机制(std :: future是任务,而std :: promise是TaskCompletionSource,用法也非常相似!) - C++协同调度程序(如果有的话)依赖于某种类似的机制来执行行为吗?
[编辑]:在做了一些进一步的研究后,我能够编写一个非常简单但非常强大的抽象代码,称为awaitable,支持单线程和协作式多任务处理,并具有一个简单的基于thread_local的调度程序,它可以在根协同程序的线程上执行协同程序开始了.代码可以在这个github repo中找到:https://github.com/llint/Awaitable
等待是可组合的,它在嵌套级别维护正确的调用排序,并且它具有原始的让步,定时等待和从其他地方设置就绪,并且可以从中导出非常复杂的使用模式(例如只有无限循环协程当某些事件发生时被唤醒),编程模型紧跟C#Task async/await模式.请随时提供反馈.
我有以下代码:
struct M {
friend void f() {}
M() {
f(); // error: 'f' was not declared in this scope
}
};
int main() {
M m;
}
Run Code Online (Sandbox Code Playgroud)
g ++ 4.8和clang3.4都无法编译它,因为它们f在内部不可见M,或者他们说.
但是,标准给出了类似代码的示例
class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};
Run Code Online (Sandbox Code Playgroud)
并说
friend类中定义的函数位于定义它的类的(词法)范围内.
(ISO/IEC 14882:2011 11.3朋友[class.friend] p6,p7)
由此我无法理解编译器如何找不到f在使用它的同一类中定义的内容.
两个编译器都不太可能有相同的bug.
那么,我错过了什么?
是否有理由使用"规范"签名 operator=
class X {
X& operator=(const X&) = delete;
X& operator=(X&&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
而不仅仅是
class X {
void operator=(X) = delete;
};
Run Code Online (Sandbox Code Playgroud)
什么时候你想做的就是delete它?
Upd:
另外,考虑X具有显式声明的移动或复制构造函数的情况.
class X {
public:
X(X&&);
};
Run Code Online (Sandbox Code Playgroud)
在那种情况下op=(X&&)并被op=(const X&)隐式删除,但我想明确表示不允许赋值.
多行原始字符串文字可以作为预处理器宏的参数吗?
#define IDENTITY(x) x
int main()
{
IDENTITY(R"(
)");
}
Run Code Online (Sandbox Code Playgroud)
此代码不能在g ++ 4.7.2和VC++ 11(Nov.CTP)中编译.
它是编译器(词法分析器)的错误吗?
在C++中,我经常使用RAII样式的对象使代码更可靠,并在堆栈上分配它们以使代码更高效(并避免使用bad_alloc).
但是在堆栈上创建具体类的对象违反了依赖性反转(DI)原则并且防止模拟该对象.
请考虑以下代码:
struct IInputStream
{
virtual vector<BYTE> read(size_t n) = 0;
};
class Connection : public IInputStream
{
public:
Connection(string address);
virtual vector<BYTE> read(size_t n) override;
};
struct IBar
{
virtual void process(IInputStream& stream) = 0;
};
void Some::foo(string address, IBar& bar)
{
onBeforeConnectionCreated();
{
Connection conn(address);
onConnectionCreated();
bar.process(conn);
}
onConnectionClosed();
}
Run Code Online (Sandbox Code Playgroud)
我可以测试IBar::process,但我也想测试Some::foo,而不是创建真正的Connection对象.
当然我可以使用工厂,但它会使代码复杂化并引入堆分配.
另外,我不喜欢添加Connection::open方法,我更喜欢构造完全初始化和功能齐全的对象.
我会为Connection类型设置一个模板参数Some(或者foo如果将其作为自由函数提取),但我不确定它是否正确(模板看起来像许多人的黑魔法,所以我更喜欢使用动态多态)
MS Visual C++ 2015 Update 1 实现了模块提议.
以下是它的工作原理示例:
来源:
// c.ixx | // b.ixx | // a.cpp
module GM; | import GM; | import FM;
export void g() {} | module FM; | int main() { f(); }
| export void f() { g(); } |
Run Code Online (Sandbox Code Playgroud)
构建命令:
set CL=/EHsc /experimental:module # Default flags for cl.exe
cl.exe /c c.ixx # Produces c.obj, GM.ifc
cl.exe /c b.ixx # Depends on GM.ifc, produces b.obj, FM.ifc
cl.exe /c a.cpp # Depends on FM.ifc, …Run Code Online (Sandbox Code Playgroud) c++ ×8
c++11 ×2
go ×2
async-await ×1
c++-modules ×1
cmake ×1
coroutine ×1
crtp ×1
json ×1
raii ×1
rtti ×1
typeid ×1
typeinfo ×1
unit-testing ×1
visual-c++ ×1