小编Wal*_*ter的帖子

使用表达式找不到模板化的静态constexpr成员函数

对于以下代码

#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也会出现这种情况.

c++ templates using-directives constexpr c++11

13
推荐指数
1
解决办法
3884
查看次数

为什么C++在一个自动语句中不允许多种类型?

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++ for-loop auto c++11

13
推荐指数
2
解决办法
4397
查看次数

如何制作一个简单的C++程序,其中没有刷新std :: cout

为了更好地理解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)

即使我强制运行时出错,看起来缓冲区在终止时仍然会被刷新.是否有可能在缓冲区中"绑定"某些数据,使其不被写入设备?

c++ buffer cout stdout stream

13
推荐指数
2
解决办法
1506
查看次数

const vs非容器及其内容的const

对于容器类,例如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++ containers const

12
推荐指数
1
解决办法
6145
查看次数

pack(类型擦除)随机数生成器

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++标准对随机数生成器有一个拙劣的界面?

c++ random c++11

12
推荐指数
1
解决办法
387
查看次数

T*中std :: unique_ptr <T>的构造函数背后的原因是什么?

由于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++ explicit-constructor unique-ptr c++11

12
推荐指数
2
解决办法
757
查看次数

应该(在C++ 11中)std :: vector :: resize(size_type)是否适用于默认的可构造的value_type int [4]?

在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是错误的.哪一个?

c++ default-constructor stdvector c++11

11
推荐指数
1
解决办法
649
查看次数

clang和Apple clang之间的区别?

我刚刚通过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)

macos macports clang

11
推荐指数
1
解决办法
3116
查看次数

如何提升使用c ++ 11?

Boost本质上是一个c ++ 03库(它刺激了c ++ 11标准).我正在考虑使用一些boost库(那些未在c ++ 11中实现的库).如果我正在使用c ++ 11,那么是否会增强编译(可能存在不可复制但可移动的对象的问题)?如何利用c ++ 11特性提升(变量模板是一个显而易见的东西[通过一些升级库]而不是大部分的升压MPL)?(我在增强常见问题解答中找不到这个).

c++ boost c++11

10
推荐指数
1
解决办法
1207
查看次数

提取和重新插入地图的限制性规则的基本原理

从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(),节点重新链接到树中,并且所有权将再次由地图接管.

因此,在该过程中不重新分配,移动或复制节点(以及存储的keymapped_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)

c++ undefined-behavior language-lawyer c++17

10
推荐指数
2
解决办法
212
查看次数