标签: c++14

为什么在C++ 14中使用std :: bind over lambdas?

在C++ 11之前我使用过boost::bind或者boost::lambda很多.该bind部分使其成为标准库(std::bind),另一部分成为核心语言(C++ lambdas)的一部分,并使lambdas的使用变得更加容易.如今,我几乎没用std::bind,因为我几乎可以用C++ lambdas做任何事情.std::bind我可以想到一个有效的用例:

struct foo
{
  template < typename A, typename B >
  void operator()(A a, B b)
  {
    cout << a << ' ' << b;
  }
};

auto f = bind(foo(), _1, _2);
f( "test", 1.2f ); // will print "test 1.2"
Run Code Online (Sandbox Code Playgroud)

相当于C++ 14的等价物

auto f = []( auto a, auto b ){ cout << a << ' ' << b; }
f( "test", 1.2f …
Run Code Online (Sandbox Code Playgroud)

c++ lambda bind c++14

56
推荐指数
3
解决办法
3万
查看次数

为什么模板参数替换的顺序很重要?

C++ 11

14.8.2 - 模板参数扣除 -[temp.deduct]

7替换发生在函数类型和模板参数声明中使用的所有类型和表达式中.表达式不仅包括常量表达式如那些出现在数组边界或无类型模板参数而且一般表达式(即非常量表达式)的内部sizeof,decltype和其它上下文允许非常量表达式.


C++ 14

14.8.2 - 模板参数扣除 -[temp.deduct]

7替换发生在函数类型和模板参数声明中使用的所有类型和表达式中.表达式不仅包括常量表达式如那些出现在数组边界或无类型模板参数而且一般表达式(即非常量表达式)的内部sizeof,decltype和其它上下文允许非常量表达式.替换以词汇顺序进行,并在遇到导致演绎失败的条件时停止.



添加的句子明确说明了在C++ 14中处理模板参数时的替换顺序.

替换顺序通常不会引起很多关注.我还没有找到一篇关于其重要性的论文.也许这是因为C++ 1y尚未完全标准化,但我认为必须引入这样的改变是有原因的.

问题:

  • 为什么以及何时,模板参数替换的顺序是否重要?

c++ templates language-lawyer c++11 c++14

56
推荐指数
1
解决办法
3068
查看次数

是否定义了std :: is_unsigned <bool> :: value?

我想知道是否

std::is_unsigned<bool>::value
Run Code Online (Sandbox Code Playgroud)

根据标准是否明确定义?

我问这个问题因为typename std::make_unsigned<bool>::type没有明确定义.

c++ unsigned boolean language-lawyer c++14

56
推荐指数
4
解决办法
2716
查看次数

将用户定义的文字用于字符串而不是字符串文字的优点

SO文档中的字符串主题用于说明,在备注部分:

由于C++ 14,而是采用"foo",则建议使用"foo"s,因为s是一个字符串,其将const char * "foo"std::string "foo".

我看到的唯一优势

std::string str = "foo"s;
Run Code Online (Sandbox Code Playgroud)

代替

std::string str = "foo";
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,编译器可以执行copy-elision(我认为),这比第二种情况下的构造函数调用要快.

尽管如此,这是(尚未)保证,因此第一个也可能会调用构造函数,即复制构造函数.

忽略需要使用std::string文字的情况

std::string str = "Hello "s + "World!"s;
Run Code Online (Sandbox Code Playgroud)

使用std::string文字而不是const char[]文字是否有任何好处?

c++ string user-defined-literals c++14

54
推荐指数
3
解决办法
3192
查看次数

Eric Niebler如何实现std :: is_function?

上周,埃里克Niebler 啾啾了一个非常紧凑的实现std::is_functiontraits类:

#include <type_traits>

template<int I> struct priority_tag : priority_tag<I - 1> {};
template<> struct priority_tag<0> {};

// Function types here:
template<typename T>
char(&is_function_impl_(priority_tag<0>))[1];

// Array types here:
template<typename T, typename = decltype((*(T*)0)[0])>
char(&is_function_impl_(priority_tag<1>))[2];

// Anything that can be returned from a function here (including
// void and reference types):
template<typename T, typename = T(*)()>
char(&is_function_impl_(priority_tag<2>))[3];

// Classes and unions (including abstract types) here:
template<typename T, typename = int T::*>
char(&is_function_impl_(priority_tag<3>))[4];

template <typename T>
struct is_function
    : …
Run Code Online (Sandbox Code Playgroud)

c++ templates type-traits c++11 c++14

54
推荐指数
1
解决办法
3697
查看次数

C++ 14变量模板:它们的目的是什么?任何用法示例?

C++ 14将允许创建模板化的变量.通常的例子是变量'pi',可以读取它以获得各种类型的数学常数π的值(3表示int;可能的最接近的值float等)

除此之外,我们可以通过将变量包装在模板化的结构或类中来实现此功能,这与类型转换如何混合?我看到一些重叠.

除了pi示例之外,它如何与非const变量一起使用?任何用法示例,以了解如何充分利用此类功能及其目的是什么?

c++ templates rationale c++14

52
推荐指数
5
解决办法
3万
查看次数

如何从移动捕获lambda表达式创建一个std :: function?

我正在尝试创建std::function一个移动捕获lambda表达式.请注意,我可以创建一个移动捕获lambda表达式而不会出现问题; 只有当我尝试将其包装成一个std::function我得到错误时.

例如:

auto pi = std::make_unique<int>(0);

// no problems here!
auto foo = [q = std::move(pi)] {
    *q = 5;
    std::cout << *q << std::endl;
};

// All of the attempts below yield:
// "Call to implicitly-deleted copy constructor of '<lambda...."

std::function<void()> bar = foo;
std::function<void()> bar{foo};
std::function<void()> bar{std::move(foo)};
std::function<void()> bar = std::move(foo);
std::function<void()> bar{std::forward<std::function<void()>>(foo)};
std::function<void()> bar = std::forward<std::function<void()>>(foo);
Run Code Online (Sandbox Code Playgroud)

我会解释为什么我要写这样的东西.我写了一个UI库,类似于jQuery的或JavaFX的,允许用户通过传递给处理鼠标/键盘事件std::functions到方法有相似的名字on_mouse_down(),on_mouse_drag(),push_undo_action(),等.

显然,std::function我想要传入的理想情况下应该使用移动捕获lambda表达式,否则我需要求助于我在C++ 11作为标准时使用的丑陋的"release/acquire-in-lambda"习语:

std::function<void()> baz = …
Run Code Online (Sandbox Code Playgroud)

c++ lambda std c++14

52
推荐指数
3
解决办法
7066
查看次数

如何在Lambda本身中获取C ++ Lambda函数的地址?

我试图弄清楚如何在自身中获取lambda函数的地址。这是一个示例代码:

[]() {
    std::cout << "Address of this lambda function is => " << ????
}();
Run Code Online (Sandbox Code Playgroud)

我知道我可以在变量中捕获lambda并打印地址,但是我想在执行此匿名函数时就地执行此操作。

有没有更简单的方法?

c++ lambda c++11 c++14 c++17

52
推荐指数
3
解决办法
4314
查看次数

用g ++编译c ++ 14代码

我在Ubuntu 14.04 LTS上使用g ++ 4.8.4.当尝试使用'-std = c ++ 14'进行编译时,我收到此错误:

g++: error unrecognized command line option '-std=c++14'
Run Code Online (Sandbox Code Playgroud)

使用'-std = c ++ 11'编译工作正常,所以我不确定发生了什么.g ++真的不支持c ++ 14吗?我使用错误的命令行选项吗?

我使用"sudo apt-get install g ++"应该会自动检索最新版本,这是正确的吗?

c++ g++ ubuntu-14.04 c++14

51
推荐指数
3
解决办法
9万
查看次数

删除了默认构造函数.仍然可以创建对象......有时候

c ++ 11统一初始化语法的天真,乐观和哦......错误的观点

我认为,因为C++ 11用户定义的类型对象应该使用新{...}语法而不是旧(...)语法构造(除了构造函数重载std::initializer_list和类似参数(例如std::vector:size ctor vs 1 elem init_list ctor)).

好处是:没有狭义的隐式转换,最烦人的解析没有问题,一致性(?).我没有看到任何问题,因为我认为它们是相同的(除了给出的例子).

但他们不是.

一个纯粹疯狂的故事

{}调用默认的构造函数.

......除非:

  • 删除默认构造函数
  • 没有定义其他构造函数.

然后它看起来像是值而不是初始化对象?...即使对象已经删除了默认构造函数,{}也可以创建一个对象.这不是打败了删除的构造函数的全部目的吗?

......除非:

  • 该对象有一个删除的默认构造函数和
  • 其他构造函数定义.

然后失败了call to deleted constructor.

......除非:

  • 该对象有一个删除的构造函数和
  • 没有其他构造函数定义和
  • 至少是一个非静态数据成员.

然后失败并丢失了字段初始值设定项.

但是,您可以使用它{value}来构造对象.

好吧也许这与第一个异常相同(值init对象)

......除非:

  • 该类有一个删除的构造函数
  • 并且至少有一个数据成员默认初始化.

然后也{}不能{value}创建一个对象.

我相信我错过了一些.具有讽刺意味的是,它被称为统一初始化语法.我再说一遍:UNIFORM初始化语法.

这种疯狂是什么?

情景A.

删除默认构造函数:

struct foo {
  foo() = delete;
};

// All bellow OK (no errors, no warnings) …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer aggregate-initialization list-initialization c++14

49
推荐指数
3
解决办法
6977
查看次数