小编Jon*_*Mee的帖子

什么是int()调用?

它已被反复重复,原始类型没有构造函数.例如_bar,当我调用时,这不会初始化为0 Foo():

class Foo{
    int _bar;
};
Run Code Online (Sandbox Code Playgroud)

所以显然int()不是构造函数.但它的名字什么?

在这个例子中我会说i:(构造?初始化?fooed?)

for(int i{}; i < 13; ++i)
Run Code Online (Sandbox Code Playgroud)

Loki Astari 在这里提到该技术有某种名称.

编辑回应Mike Seymour:

#include <iostream>

using namespace std;

class Foo{
    int _bar;
public:
    void printBar(){ cout << _bar << endl; }
};

int main()
{
    Foo foo;

    foo.printBar();

    Foo().printBar();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在Visual Studio 2013上运行此代码产生:

3382592
3382592

有趣的是gcc 4.8.1收益率:

134514651
0

c++ primitive construction initialization nomenclature

15
推荐指数
2
解决办法
2193
查看次数

我的退货类型是否需要定义?

前向声明允许我们推迟定义实际类型直到实现文件.指针的头部或前向声明类型的引用允许这样做.

有人告诉我:

按值返回不需要类型定义.前瞻性声明就足够了

有人可以通过标准的实际报价来确认或否认这一点吗?我的印象是这不合法.

c++ return-type return-value forward-declaration language-lawyer

15
推荐指数
1
解决办法
1463
查看次数

any_of对比find_if

C++ 11引入any_ofalgorithms.

这似乎完全一样find_if.

说我有一个仿函数:function<bool(int)> foo; 和一个数组:vector<int> bar;

看起来这两个调用完全相同:

any_of(bar.begin(), bar.end(), foo);
Run Code Online (Sandbox Code Playgroud)

bar.end() != find_if(bar.begin(), bar.end(), foo);
Run Code Online (Sandbox Code Playgroud)

我进一步感到all_of,并且none_of可以通过否定find_if陈述来完成.

这些算法只是在这里end为我们做比较,还是有用我不明白?

c++ algorithm find c++11

14
推荐指数
2
解决办法
4368
查看次数

std :: enable_if如何工作?

我刚问了这个问题:std :: numeric_limits作为一个条件

我理解用于std::enable_if定义有条件地导致该方法无法编译的方法的返回类型的用法.

template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar); }
Run Code Online (Sandbox Code Playgroud)

我不明白的是第二个参数和看似无意义的赋值,std::enable_if当它被声明为模板语句的一部分时,如Rapptz的 回答.

template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& bar) { isInt(); }
Run Code Online (Sandbox Code Playgroud)

c++ templates enable-if c++11

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

在嵌套的Lambda中捕获Lambda的静态

这个答案中,我使用此代码:

std::vector<std::vector<int>> imat(3, std::vector<int>(10));

std::for_each(imat.begin(), imat.end(), [&](auto& i) {
    static auto row = 0;
    auto column = 0;
    std::transform(i.begin(), i.end(), i.begin(), 
        [&](const auto& /*j*/) {
            return row * column++; 
    }); 

    ++row; 
});
Run Code Online (Sandbox Code Playgroud)

但我注意到static auto row根据编译器捕获的一些不当行为.

Clang 3.7.0收益率:

0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18

gcc 5.1.0产量:

0 0 0 0 0 …

c++ lambda capture language-lawyer c++14

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

非解除引用的迭代器是否超过了数组未定义行为的"一个接一个"的迭代器?

鉴于int foo[] = {0, 1, 2, 3};我想知道指向过去"一个过去"的迭代器是否无效.例如:auto bar = cend(foo) + 1;

有大量的抱怨和警告,这是Stack Overflow问题中的"未定义行为",如下所示:c ++当过去结束迭代器时,迭代器+整数的结果是什么?不幸的是,唯一的来源是挥手.

我购买它的麻烦越来越多,例如:

int* bar;
Run Code Online (Sandbox Code Playgroud)

是未初始化的,但肯定不会调用未定义的行为,并且给定了足够的尝试,我确信我可以找到一个实例,其中未初始化的值bar具有相同的值cend(foo) + 1.

这里最大的困惑之一是我不会要求解除引用cend(foo) + 1.我知道这将是未定义的行为,标准禁止它.但是这样的答案:https://stackoverflow.com/a/33675281/2642059只引用解除引用这样的迭代器是非法的,回答这个问题.

我也知道C++只保证它cend(foo)是有效的,但它可能会numeric_limits<int*>::max()在这种情况下cend(foo) + 1溢出.我对这种情况不感兴趣,除非它在标准中被调出,因为我们不能让迭代器超过"一个接一个结束".我知道这int*只是一个整数值,因此会受到溢出的影响.

我想从一个可靠的来源引用一个引用,即将迭代器移到"一个接一个"的元素之外是未定义的行为.

c++ arrays pointers iterator language-lawyer

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

constexpr函数允许什么?

constexpr函数不应包含:

非文字类型变量的定义

但是在这个答案中,lambda被定义为一个:https://stackoverflow.com/a/41616651/2642059

template <typename T>
constexpr auto make_div(const T quot, const T rem)
{
    return [&]() {
        decltype(std::div(quot, rem)) result;
        result.quot = quot;
        result.rem = rem;
        return result;
    }();
}
Run Code Online (Sandbox Code Playgroud)

在我的评论中,我定义了div_t一个:如何初始化div_t对象?

template <typename T>
constexpr decltype(div(T{}, T{})) make_div(const T quot, const T rem)
{
    decltype(div(T{}, T{})) x{};
    x.quot = quot;
    x.rem = rem;
    return x;
}
Run Code Online (Sandbox Code Playgroud)

究竟是什么意思禁止"非字面型变量的定义"?

Visual Studio 2015将不允许我对a的定义,div_t但我发现在lambda中包含这些非法行为并执行它是允许的,这是荒谬的.我想知道哪个编译器在div_t定义方面表现正常.

c++ function constexpr c++14 c++17

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

为什么GCC 6.3在没有明确的C++ 11支持的情况下编译这个Braced-Init-List代码?

我有一个关于卷括号括号列表的不同含义的问题.

我知道C++ 03不支持C++ 11 initializer_list.然而,即使没有-std=c++11编译器标志,gcc 6.3 也会interpolate使用以下代码正确初始化:

map<string, string> interpolate = { { "F", "a && b && c" }, { "H", "p ^ 2 + w" }, { "K", "H > 10 || e < 5" }, { "J", "F && !K" } };
Run Code Online (Sandbox Code Playgroud)

我被问到为什么这会起作用,我意识到我没有答案.这是一个Brace-Init-List,但我们从初始化标准容器的方式通常是通过initializer_list.那么非C++ 11代码如何完成初始化呢?

c++ gcc initializer-list c++03 list-initialization

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

为什么我不能从iterator_traits获取value_type?

我这样做:

const int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const auto foo = cbegin(arr);
const typename iterator_traits<decltype(foo)>::value_type bar = 1;
Run Code Online (Sandbox Code Playgroud)

我本来期望bar有这种类型int.但相反,我得到一个错误:

错误C2039 :: value_type不是.的成员std::iterator_traits<_Ty *const >

这是const我需要剥离那个什么的问题吗?

c++ types iterator typename iterator-traits

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

按值传递参考参数

考虑这个简单的程序:

vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), foo.front(), 13);

for(const auto& i : foo) cout << i << '\t';
Run Code Online (Sandbox Code Playgroud)

当我写它时我希望得到:

13 42 13 42 13 42

但相反,我得到了:

13 42 0 42 0 42

问题当然是replace通过引用获取最后2个参数.因此,如果它们中的任何一个碰巧处于正在操作的范围内,结果可能是意外的.我可以通过添加临时变量解决这个问题:

vector<int> foo = {0, 42, 0, 42, 0, 42};
const auto temp = foo.front();
replace(begin(foo), end(foo), temp, 13);

for(const auto& i : foo) cout << i << '\t';
Run Code Online (Sandbox Code Playgroud)

我知道C++ 11为我们提供了各种类型的工具,我可以简单地将这个值强制转换为非引用类型并传递内联,而不创建临时的吗?

c++ reference pass-by-reference pass-by-value c++11

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