我试图用c ++ 11统一初始化来解决一些极端情况,我无法弄清楚为什么会这样:
struct Base
{
int x,y,z;
};
struct Derived : Base
{
};
static_assert (std::is_trivial<Base>::value, "Base must be trivial");
static_assert (std::is_trivial<Derived>::value, "Derived must be trivial");
Base b{1, 2, 3}; // 1) This compiles fine
Derived d{10, 20, 30}; // 2) This fails
Run Code Online (Sandbox Code Playgroud)
标记为2的行失败,并带有"无用于初始化Derived的匹配构造函数"消息clang 3.1和g++ 4.7.
我无法理解为什么,在Derived的情况下,它试图调用构造函数而不执行(我不知道如何调用它,可能是聚合初始化?),就像第1行的情况一样.
以下推理中的某些内容是错误的?:
A)微不足道的保证它可以静态初始化
B)要静态初始化没有代码必须在运行时执行,因此不需要构造函数调用
A+B=>为什么它试图在一个它知道微不足道的类型上调用构造函数?
我很困惑....
c++ inheritance uniform-initialization c++11 list-initialization
这个代码,其中有一个const A& a成员B,其中A有一个已删除的拷贝构造函数,不能在GCC 4.8.1中编译,但它在clang 3.4中工作正常:
class A {
public:
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B{
public:
B(const A& a)
: a{a}
{ }
private:
const A& a;
};
int main()
{
A a{};
B b{a};
}
Run Code Online (Sandbox Code Playgroud)
哪一个编译器是对的?
GCC中的错误是:
prog.cpp: In constructor ‘B::B(const A&)’:
prog.cpp:11:14: error: use of deleted function ‘A::A(const A&)’
: a{a}
^
prog.cpp:4:5: error: declared here
A(const A&) = delete;
^
Run Code Online (Sandbox Code Playgroud)
Ideone:http …
struct S
{
int x;
int y;
};
std::atomic<S> asd{{1, 2}}; // what should this be? This doesn't work
Run Code Online (Sandbox Code Playgroud)
编辑:这两个{{1, 2}}和({1, 2})在G ++,在铛没有工作的工作.clang有解决方法吗?
c++ atomic aggregate-initialization uniform-initialization c++11
根据: constexpr静态数据成员给出未定义的引用错误 静态constexpr类成员必须满足两个要求:
template <typename Tp>
struct wrapper {
static constexpr Tp value{}; // 1
};
template<typename Tp>
constexpr Tp wrapper<Tp>::value; // 2
struct foo {
};
int main() {
auto const& x = wrapper<foo>::value;
(void)x;
}
Run Code Online (Sandbox Code Playgroud)
如果我改变1.统一初始化
template <typename Tp>
struct wrapper {
static constexpr auto value = Tp{}; // uniform initialization
};
template<typename Tp>
constexpr Tp wrapper<Tp>::value;
Run Code Online (Sandbox Code Playgroud)
编译器抱怨冲突的声明:
$ g++ prog.cc -Wall -Wextra -std=c++1z -pedantic
prog.cc:7:31: error: conflicting declaration 'constexpr const Tp wrapper<Tp>::value' constexpr Tp wrapper<Tp>::value; …Run Code Online (Sandbox Code Playgroud) 这个问题也已提交给Usenet,它更合适,但这是一个更大,更可靠的论坛.
std::allocator::construct 被定义为使用括号将其参数参数包转发给对象构造,即直接初始化.
如果它使用大括号,即统一初始化,我们可以从诸如std::make_shared和之
类的函数初始化聚合数据类型container::emplace.另外,将初始化列表的内容放入这样的函数的参数列表中是可以接受的,解决了initializer_list转发下的类型推导问题.
这个选择是否被考虑和拒绝了?切换到未来的标准是否为时已晚?这似乎是一个突破性的变化,但不是特别令人发指的变化.
我有这个代码来初始化map到unique_ptr.
auto a = unique_ptr<A>(new A());
map<int, unique_ptr<A>> m;
m[1] = move(a);
Run Code Online (Sandbox Code Playgroud)
我可以使用统一初始化吗?我试过了
map<int, unique_ptr<A>> m {{1, unique_ptr<A>(new A())}};
Run Code Online (Sandbox Code Playgroud)
但是我收到了一个错误.
错误消息的某些部分是
In instantiation of 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, std::unique_ptr<A, std::default_delete<A> > >&}; _Val = std::pair<const int, std::unique_ptr<A> >]': ... In file included from /opt/local/include/gcc48/c++/memory:81:0,
from smart_pointer_map.cpp:3: /opt/local/include/gcc48/c++/bits/unique_ptr.h:273:7: error: declared here
unique_ptr(const unique_ptr&) = delete;
^
Run Code Online (Sandbox Code Playgroud) 可以使用迭代器范围构造一个向量,如下所示:
std::vector<std::string> vec(std::istream_iterator<std::string>{std::cin},
std::istream_iterator<std::string>{});
Run Code Online (Sandbox Code Playgroud)
但我也可以使用C++ 11统一初始化语法编译和运行代码(注意括号),如下所示:
std::vector<std::string> vec{std::istream_iterator<std::string>{std::cin},
std::istream_iterator<std::string>{}};
Run Code Online (Sandbox Code Playgroud)
这里到底发生了什么?
我知道采用初始化列表的构造函数优先于其他形式的构造.编译器是否应该解析为构造函数采用包含2个元素的初始化列表std::istream_iterator?这应该是一个错误,因为std::istream_iterator无法转换为矢量值类型std::string,对吧?
"我们可以初始化一个类的对象,我们没有使用它来定义任何构造函数:
- 成员初始化.
- 复制初始化.
- 默认初始化.
例如:
Run Code Online (Sandbox Code Playgroud)struct Work { string author; string name; int year; }; Work s9 { "Bethoven", "Symphony No. 9 in D minor, Op. 125; Choral", 1824 }; // memberwise initialization Work currently_playing {s9}; // copy initialization Work none {}; // default initialization
C++编程语言第四版.第17.3.1节
例如:
struct Data
{
int mMember1;
float mMember2;
char mMember3;
};
int main()
{
Data aData_1{1,0.3,33};
Data aData_2{aData_1};
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
这必须起作用,虽然我得到的编译器错误与GCC一样多,与Clang一样多.两个编译器中的错误是"无法将数据转换为int".但是,实现复制构造函数时,此错误会消失,或者不使用圆括号语法实现它.问题是有点愚蠢,并改变圆形括号的卷曲问题得到解决.但为什么TC++ PL的规则没有被遵循?,是一个编译器问题还是我误解了什么?提前致谢.
使用-std = c ++ 11时,以下代码在gcc 4.9.1和clang-3.6中编译和运行:
struct Bar
{
int x;
};
struct Foo
{
static constexpr Bar bars[] = {1, 2, 3};
};
constexpr Bar Foo::bars[];
Run Code Online (Sandbox Code Playgroud)
但是,它在gcc 4.8.3中失败,导致错误消息
./cpptest.cpp:14:43: error: could not convert '1' from 'int' to 'const Bar'
static constexpr Bar bars[] = {1, 2, 3};
^
./cpptest.cpp:14:43: error: could not convert '2' from 'int' to 'const Bar'
./cpptest.cpp:14:43: error: could not convert '3' from 'int' to 'const Bar'
Run Code Online (Sandbox Code Playgroud)
顺便说一下,如果我做同样的事情但是创建bars一个静态const全局数组,它在gcc 4.8和clang中编译得很好.如果我用额外的一对包围列表中的每个整数文字,它也会编译得很好{}.
这是gcc 4.8中的一个错误吗?标准所说的是适当的语法?当我省略额外的括号时,调用c ++ …
如果尝试对进行统一的初始化,则会得到不同的结果std::set。
例:
int main()
{
std::array a {1,2,3,4};
std::set<int> s1 {a.begin(), a.end()};
std::set s2 {a.begin(), a.end()};
std::set s3 (a.begin(), a.end());
for(auto& i: s1) { std::cout << i << "\n"; }
std::cout << "####" << std::endl;
for(auto& i: s2) { std::cout << i << "\n"; }
std::cout << "####" << std::endl;
for(auto& i: s3) { std::cout << i << "\n"; }
}
Run Code Online (Sandbox Code Playgroud)
结果是:
1
2
3
4
####
0x7ffecf9d12e0
0x7ffecf9d12f0
####
1
2
3
4
Run Code Online (Sandbox Code Playgroud)
这似乎与“演绎指南”有关,如果与{}或() …