对于以下代码
#include <array>
template<unsigned MaxP, typename type>
struct kernel
{
static constexpr unsigned max_pole(unsigned P)
{ return P>MaxP? MaxP:P; }
template<unsigned P>
using array = std::array<type,max_pole(P)>; // wrong?
template<unsigned P>
static void do_something(array<P> const&, array<P>&);
};
Run Code Online (Sandbox Code Playgroud)
gcc 4.7.0(g ++ -c -std = c ++ 11)给出
error: ‘max_pole’ was not declared in this scope
Run Code Online (Sandbox Code Playgroud)
这是正确的(编译器的行为)吗?请注意,如果我max_pole通过kernel::max_pole在指定的行上替换它来解决它,它编译得很好.
编辑报告给bugzilla,接受为bug c ++/55992,请参阅http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55992.gcc 4.7.x和4.8.0也会出现这种情况.
2011 C++标准引入了new关键字auto,可用于定义变量而不是类型,即
auto p=make_pair(1,2.5); // pair<int,double>
auto i=std::begin(c), end=std::end(c); // decltype(std::begin(c))
Run Code Online (Sandbox Code Playgroud)
在第二行中,i并且end具有相同的类型,被称为的auto.该标准不允许
auto i=std::begin(container), e=std::end(container), x=*i;
Run Code Online (Sandbox Code Playgroud)
什么时候x会有不同的类型.我的问题:为什么标准不允许这最后一行?可以通过将其解释auto为不代表某些待定的类型,而是指示所声明的任何变量的类型auto应从其指定值推导出来.C++ 11标准有没有很好的理由不遵循这种方法?
实际上有一个用例,即在for循环的初始化语句中:
for(auto i=std::begin(c), end=std::end(c), x=*i; i!=end; ++i, x+=*i)
{ ... }
Run Code Online (Sandbox Code Playgroud)
当变量的范围i,end以及x被限制在for环路.AFAIK,除非这些变量具有通用类型,否则无法在C++中实现.它是否正确?(将所有类型放入struct排除的丑陋技巧)
在一些可变参数模板应用程序中也可能存在用例.
为了更好地理解C++中的缓冲流,我想编写一个简单的程序,std::cout在终止之前不刷新缓冲区.由于我已经读取了std::cout在正常终止时刷新,我尝试抛出运行时错误.我也避免使用std::endl,据我所知,强制冲洗.第一次尝试:
//file noflush.cpp
#include <iostream>
int main() {
std::cout << "Don't write me to the console!";
throw 0;
}
Run Code Online (Sandbox Code Playgroud)
用g ++编译,从终端调用:
$ ./noflush
libc++abi.dylib: terminating with uncaught exception of type int
Don't write me to the console!Abort trap: 6
Run Code Online (Sandbox Code Playgroud)
即使我强制运行时出错,看起来缓冲区在终止时仍然会被刷新.是否有可能在缓冲区中"绑定"某些数据,使其不被写入设备?
对于容器类,例如std::vector,有两个不同的常量概念:容器的概念(即它的大小)和元素的概念.似乎std::vector混淆了这两个,这样下面的简单代码就不会编译:
struct A {
A(size_t n) : X(n) {}
int&x(int i) const { return X[i]; } // error: X[i] is non-const.
private:
std::vector<int> X;
};
Run Code Online (Sandbox Code Playgroud)
需要注意的是,即使数据成员(三个指针指向数据的开始和结束,所分配的缓冲区的结束)std::vector都没有通过其呼叫改变operator[],这件是不是const-是不是这样一个奇怪的设计?
还要注意,对于原始指针,这两个常量概念是完全分开的,这样相应的原始指针代码
struct B {
B(size_t n) : X(new int[n]) {}
~B() { delete[] X; }
void resize(size_t n); // non-const
int&x(int i) const { return X[i]; } // fine
private:
int*X;
};
Run Code Online (Sandbox Code Playgroud)
工作得很好.
那么使用std::vector(不使用mutable)时处理这个问题的正确/推荐方法是什么?
是一个const_cast<> …
C++ 11 std库有几个随机数生成器(RNG),每个生成器实现UniformRandomNumberGenerator概念.然后可以将它们用作随机分布的参数,另请参阅此文档以获取概述.
这种设计的优点是底层RNG引擎的选择与其应用分离.但是,该设计还要求对RNG的所有调用的定义(不仅仅是声明)是可用的(如果RNG类型仍未指定为模板参数).因此,在
struct complicated_random_distribution
{
/*
some data and auxiliary methods here
*/
// complicated; may call RNG::operator() many times
template<typename RNG>
some_type operator()(RNG&gen) const;
};
Run Code Online (Sandbox Code Playgroud)
该成员operator()不能直接在单独的编译单元(CU)中实现,但必须在相同的头文件中(或#include从其中一个d)中可用.
对于单独的实现,理想情况下,想要某种方式来打包RNG的方式与std::function<>打包任何可调用对象的方式相同.(简单地使用std::function和提供单独CU中定义的函数的值RNG::min()和RNG::max()作为参数是限制性的,并且不允许使用,例如,std::uniform_real_distribution<>在内部).
如何才能做到这一点?这个实现是否可用?std库将来会提供这个吗?还是我在吃了一只红鲱鱼?
编辑随机数生成器需要有static成员,min()并且max()使类型擦除变得困难或不可能(GNU的libstdc ++没有做出这种假设,并且使用非静态成员进行类型擦除min()和max()工作,但不能使用LLVM的libc ++,它使用所需的标准static成员).还有办法还能解决这个问题吗?如果没有,这是否意味着C++标准对随机数生成器有一个拙劣的界面?
由于std::unique_ptr提供了一种避免内存泄漏并确保异常安全的便捷方法,因此传递它们而不是原始指针是明智的.因此,人们可能想要具有签名的(成员)函数
std::unique_ptr<some_type> foo(some data);
Run Code Online (Sandbox Code Playgroud)
不幸的是,在实现这样的功能时,不能简单地
std::unique_ptr<some_type> foo(some data)
{
return { new some_type(data) }; // error
}
Run Code Online (Sandbox Code Playgroud)
但必须改为
std::unique_ptr<some_type> foo(some data)
{
return std::move( std::unique_ptr<some_type>( new some_type(data) ) ); // awkward
}
Run Code Online (Sandbox Code Playgroud)
因为构造函数unique_ptr::unique_ptr(pointer)是explicit.这个构造函数背后的原因是explicit什么?
构造函数的一个动机explicit是防止意外的隐式类型转换.但是,由于unique_ptr不能通过价值传递,这应该不是一个真正的问题,是吗?
在C++ 11中,有两个版本std::vector::resize():
void resize( size_type count );
void resize( size_type count, const value_type& value);
Run Code Online (Sandbox Code Playgroud)
我理解(正如对该问题的答案之一的评论之一所建议的),第一个要求value_type是默认可构造的,而第二个要求它是可复制构造的.但是,(gcc 4.7.0)
using namespace std;
typedef int block[4];
vector<block> A;
static_assert(is_default_constructible<block>::value,";-("); // does not fire
A.resize(100); // compiler error
Run Code Online (Sandbox Code Playgroud)
所以要么我的理解是错误的,要么gcc是错误的.哪一个?
我刚刚通过mac升级到OS X 10.8.2,它带有clang.输出clang -v是:
Apple clang version 4.1 (tags/Apple/clang-421.11.65) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix
Run Code Online (Sandbox Code Playgroud)
在macports上,有几个clang版本(port search clang)
clang @2.9 (lang)
C, C++, Objective C and Objective C++ compiler
clang-2.9 @2.9 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.0 @3.0 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.1 @3.1 (lang)
C, C++, Objective C and Objective C++ compiler
clang-3.2 @3.2-r164372 (lang)
C, C++, Objective C and Objective C++ compiler …Run Code Online (Sandbox Code Playgroud) Boost本质上是一个c ++ 03库(它刺激了c ++ 11标准).我正在考虑使用一些boost库(那些未在c ++ 11中实现的库).如果我正在使用c ++ 11,那么是否会增强编译(可能存在不可复制但可移动的对象的问题)?如何利用c ++ 11特性提升(变量模板是一个显而易见的东西[通过一些升级库]而不是大部分的升压MPL)?(我在增强常见问题解答中找不到这个).
从C++ 17开始,关联容器支持节点的提取及其重新插入(可能进入另一个相同类型的容器).返回的对象extract(key)是node_handle,它是仅移动的,而映射容器具有成员函数
key_type &key() const;
mapped_type &mapped() const;
Run Code Online (Sandbox Code Playgroud)
它不仅可以改变映射类型,还可以改变密钥.这可用于更改密钥而无需重新分配(例如,从文档中获取map::extract()):
std::map<int, std::string> map{{1,"mango"}, {2,"papaya"}, {3,"guava"}};
auto handle = map.extract(2);
handle.key() = 4;
map.insert(move(handle));
Run Code Online (Sandbox Code Playgroud)
据我所知,map实现为二进制搜索树,同时map::extract()从树中取消链接节点,并通过node-handle返回指向它的指针,后者接管所有权.之后map::insert(),节点重新链接到树中,并且所有权将再次由地图接管.
因此,在该过程中不重新分配,移动或复制节点(以及存储的key和mapped_type).该标准说(我的高光):
提取成员仅使删除元素的迭代器无效; 指针和对已删除元素的引用仍然有效.但是,当元素由node_type拥有时,通过这样的指针和引用访问元素是未定义的行为.如果元素成功插入,则在node_type拥有的元素的引用和指针 无效.
我的问题:背后的理由是什么(1)使UB通过其地址访问提取的元素,以及(2)在插入时使提取的状态中的地址无效?
恕我直言,这种提取和插入习语可以以一种始终保持元素地址有效的方式实现(直到破坏,如果永远不重新插入元素,可能在地图破坏之前发生).以下代码
#include <map>
#include <string>
#include <iostream>
struct immovable_string : std::string
{
immovable_string(const char*s) : std::string(s) {}
immovable_string() = default;
immovable_string(immovable_string const&) = delete;
immovable_string(immovable_string …Run Code Online (Sandbox Code Playgroud)