考虑以下代码:
struct Foo{
std::string s1;
std::string s2;
};
int main(){
Foo f{.s1 = "s1", .s2 = f.s1 + "s2"};
std::cout << "s1='" << f.s1 << "', s2='" << f.s2 << "'" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
特别注意 的初始化访问:s2的第一个成员。最新的 clang、gcc 和 MSVC 对代码很满意,并给出了天真的预期结果(它们打印)。观看Godbolt直播。f.s2 = f.s1 + "s2""s1='s1', s2='s1s2'"
问题:这合法吗?换句话说,标准是否保证在f.s1指定的初始化器被.s2评估之前被初始化?
相关:有一个类似的问题询问是否.s2 = .s1 + "s2"合法,这显然是不合法的,因为它无法编译。另外,P0328(根据此答案)可能相关,但我看不到我的问题在那里得到解答。
c++ designated-initializer language-lawyer aggregate-initialization c++20
根据文档,Objective-C中类的指定初始值设定项必须调用其基类的指定初始值设定项.
另一个规则是辅助初始化程序必须调用它们自己的类的指定初始化程序.
但是如果遵循第二条规则,为什么指定的初始化程序不能在其基类中调用辅助初始化程序?这个基础辅助初始化程序最终将调用它自己的级别的DI,因此该对象仍将被正确初始化,对吧?
差异似乎是谁选择缺失变量的默认值 - 您或您的基类.
我正在读一本有指导原则的书:
"如果一个类声明了一个与其超类不同的指定初始值设定项,则必须重写超类的指定初始值设定项以调用新的指定初始值设定项"
据我所知,这个指导就是说,如果我将我的类子类化为它的超类,并且我的子类有一个与des不同的指定初始化器.它的超类的初始化程序,然后在我的子类中,我必须覆盖我的超类的指定初始化程序,并在其内部调用我的子类的指定初始化程序.
这是真的?我们必须一直这样做吗?谢谢.
overriding initialization class objective-c designated-initializer
在我阅读C++参考时,我对这一段有疑问:
注意:C编程语言支持无序指定初始化,嵌套指定初始化,指定初始化器和常规初始化器的混合以及指定的数组初始化,但C++中不允许这样做.
是否有任何技术原因阻止C++支持无序指定初始化?
有没有一种很好的方法来组合来自C99的指定初始化器,结果是malloc?
以下似乎有不必要的重复:
typedef struct {
int a, b, c;
} Type;
Type *t = malloc(sizeof *t);
*t = (Type) {
.a = 2,
.b = 3,
.c = 5,
};
Run Code Online (Sandbox Code Playgroud)
可以使用Type,并*t从上面的代码中删除?
指定的初始化程序(C ++ 20)应该如何与CTAD一起使用?
这段代码在gcc9.2中可以正常工作,但在clang8中失败
template <typename int_t=int, typename float_t=float>
struct my_pair {
int_t first;
float_t second;
};
template<typename ... ts>
my_pair(ts...) -> my_pair<ts...>;
int main() {
my_pair x{.first = 20, .second = 20.f};
static_assert( std::is_same_v<decltype(x.first), int> );
static_assert( std::is_same_v<decltype(x.second), float> );
}
Run Code Online (Sandbox Code Playgroud)
这应该是有效的吗?
c++ designated-initializer class-template argument-deduction c++20
我已经在这个问题中对使用指定的初始化程序的CTAD感到困惑,但是我对另一个非常相似的代码段也感到困惑
template <typename int_t=int, typename float_t=float>
struct my_pair {
int_t first;
float_t second;
};
template<typename ... ts>
my_pair(ts...) -> my_pair<ts...>;
int main() {
my_pair x{.second = 20.f};
static_assert( std::is_same_v<decltype(x.first), int> ); //FAILS <- its deduced to float
static_assert( std::is_same_v<decltype(x.second), float> );
}
Run Code Online (Sandbox Code Playgroud)
即使我没有在指定的初始值设定项中给出显式信息,推论指南似乎也将推导类型first推导为。无论关键字(),推论指南显然只关心初始化程序中的顺序。演绎指南应该明智吗?还是应该有一个“指定演绎指南”?float.first.second
请参阅https://godbolt.org/z/cm6Yi7上的示例
考虑以下代码:
struct A{
int x;
int y;
};
struct B{
int y;
int x;
};
void func (A){
}
void func (B){
}
int main()
{
func({.y=1,.x=1});
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,clang 和 gcc 都认为这段代码是不明确的,尽管已知指定初始值设定项中的顺序必须与 struct 中的顺序相匹配,尽管出于某种原因,clang 允许它并且只是发出警告:
ISO C++ 要求在声明顺序中指定字段指示符;字段 'y' 将在字段 'x' [-Wreorder-init-list] 之后初始化
现在有趣开始了:如果我注释掉func(B)代码,代码就会从模棱两可变成无法编译。
这就是我认为超级奇怪的地方。这背后有什么逻辑吗?
如果我的困惑的原因不清楚:
如果我们有两个func(A)和func(B)代码GCC和铛考虑func({.y=1,.x=1})暧昧,但如果我删除func(B)从源则给出了一个错误(或警告铛的情况下)。换句话说,我们通过删除 1 个选项从 2 个选项变为 0 个选项。
在下面的程序中,聚合结构B具有字段a,它本身就是一个聚合。可以使用 C++20 指定初始值设定项设置其值而不用花括号括起来吗?
struct A { int i; };
struct B { A a; };
int main() {
[[maybe_unused]] B x{1}; //ok everywhere
[[maybe_unused]] B y{.a = {1}}; //ok everywhere
[[maybe_unused]] B z{.a = 1}; //ok in MSVC,Clang; error in GCC
}
Run Code Online (Sandbox Code Playgroud)
MSVC 和 Clang 编译器接受此代码。但是 GCC 发出了一个奇怪的错误:
error: 'A' has no non-static data member named 'a'
Run Code Online (Sandbox Code Playgroud)
演示:https : //gcc.godbolt.org/z/65j1sTcPG
是 GCC 中的错误,还是标准不允许这种初始化?
这种结构用作链表头:
struct lista
{
struct lista* next;
struct lista* prev;
};
Run Code Online (Sandbox Code Playgroud)
当next和prev都指向struct本身时,则列表为空.以下宏可用于初始化结构:
#define LISTA_INIT_EMPTY(list) { .next = (list), .prev = (list) }
Run Code Online (Sandbox Code Playgroud)
这条路:
struct lista my_list = LISTA_INIT_EMPTY(&my_list);
Run Code Online (Sandbox Code Playgroud)
但是,有没有办法通过以下方式做同样的事情,没有宏参数?:
struct lista my_list = LISTA_INIT_EMPTY;
Run Code Online (Sandbox Code Playgroud)
我尝试了以下,但它导致编译错误:
#define LISTA_INIT_EMPTY { .next = &.next, .prev = &.next }
Run Code Online (Sandbox Code Playgroud) c++ ×6
c++20 ×6
c ×2
objective-c ×2
c99 ×1
class ×1
coding-style ×1
ctad ×1
inheritance ×1
malloc ×1
overriding ×1