小编jro*_*rok的帖子

奇怪的语法 - 参数包扩展中的两个省略号运算符

可能重复:
"......"令牌是什么意思?

在查看libc ++的标题时<type_traits>,我偶然发现了这些类模板特化:

template<typename>
    struct is_function
    : public false_type { };

template<typename _Res, typename... _ArgTypes>
    struct is_function<_Res(_ArgTypes...)>
    : public true_type { };

template<typename _Res, typename... _ArgTypes>
    struct is_function<_Res(_ArgTypes......)>    // <-- Huh?
    : public true_type { };
Run Code Online (Sandbox Code Playgroud)

有三个对特(的const,volatile并且const volatile变化),都以同样的方式.

它看起来像两个elipsis运算符组合在一起.我唯一能提到的就是cplusplus.com,它说它也可以用space(_ArgTypes... ...)或逗号(_ArgTypes..., ...)编写,但没有解释它的含义.

那么,这种语法意味着什么?像这样的专业化的目的是什么?

c++ variadic-templates c++11

6
推荐指数
0
解决办法
129
查看次数

有没有办法获取QObject派生类的类名而不创建该类的实例化?

我正在寻找这样的东西:

MyClass::metaObject()->className()

这不起作用,因为在执行此代码时,不存在MyClass的实例化.

如果这在某种程度上是可能的,有没有办法获得从MyClass派生的所有类的名称?

c++ qt metaobject

6
推荐指数
2
解决办法
5247
查看次数

具有两个参数的向量构造函数被解析为函数声明

考虑这个例子:

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

int main()
{
    std::string sen = "abc def ghi jkl";
    std::istringstream iss(sen);

    std::vector<std::string>    // declaration in question
    vec(std::istream_iterator<std::string>(iss),
        std::istream_iterator<std::string>());

    std::copy(vec.begin(), vec.end(),
              std::ostream_iterator<std::string>(std::cout, "\n"));
}
Run Code Online (Sandbox Code Playgroud)

编译器在调用时抛出错误 std::copy

request for member 'begin' in 'vec', which is of non-class type...

我可以解决这个错误:

std::istream_iterator<std::string> it_begin(iss);
std::istream_iterator<std::string> it_end;
std::vector<std::string> vec(it_begin, it_end);
Run Code Online (Sandbox Code Playgroud)

或者在每个参数周围加上括号,如下所示:

std::vector<std::string>
vec((std::istream_iterator<std::string>(iss)),
    (std::istream_iterator<std::string>()));
Run Code Online (Sandbox Code Playgroud)

甚至在C++ 11中使用新的统一初始化:

std::vector<std::string> vec { /*begin*/, /*end*/ };
Run Code Online (Sandbox Code Playgroud)

为什么编译器将示例中的声明解析为函数声明?我知道最烦恼的解析,但我认为只有空参数列表才会发生.我也想知道为什么第二种解决方法有效.

c++ parsing stdvector most-vexing-parse

5
推荐指数
1
解决办法
2394
查看次数

这是合法的,以避免设置创建Comparator对象的实际副本

在这样的代码中:

Comparator comp(3);

set<string, Comparator> s1(comp);
set<string, Comparator> s2(comp);
set<string, Comparator> s3(comp);
set<string, Comparator> s4(comp); 
Run Code Online (Sandbox Code Playgroud)

比较器的实际实例(即comp)在每次创建set对象时被复制为cpp引用状态

容器保留alloc和comp的内部副本,用于分配存储并在整个生命周期内对元素进行排序.

所以我们想知道这在C++中是否合法

#include <set>
#include <iostream>

struct A {
    int i = 0;
    bool operator()(int a, int b)
    {
        ++i;
        return a < b;
    }
};

int main()
{    
    A a;
    std::set<int, A&> s1( {1, 2, 3}, a);
    std::set<int, A&> s2( {4, 5, 6}, a);
    std::cout << a.i;
}
Run Code Online (Sandbox Code Playgroud)

提前致谢.

c++ templates stl set functor

5
推荐指数
1
解决办法
87
查看次数

编译器警告:无法推断lambda返回类型

考虑这个例子:

#include <algorithm>
#include <iostream>

int main()
{
    std::string str = "abcde4fghijk4l5mnopqrs6t8uvwxyz";
    std::string str2;

    std::remove_copy_if(str.begin(), str.end(),
        std::back_inserter(str2),
        [](char& c) {
            if (std::isdigit(c))
                return true;      // <----- warning here
            else
                return false;
        }
    );

    std::cout << str2 << '\n';
}
Run Code Online (Sandbox Code Playgroud)

使用GCC 4.6.1,这可以很好地编译并打印预期的输出(字母表)但是我得到一个警告说"只有在return语句是函数体中唯一的语句时才能推断出lambda返回类型".

现在,我知道如何摆脱警告(使用尾随返回类型或只是说return isdigit(c);),但我很好奇,因为编译器没有任何警告(或者它应该是):代码中可能出错的地方像这样?标准是否对此有所说明?

c++ lambda compiler-warnings c++11

4
推荐指数
1
解决办法
690
查看次数

标准库算法是否允许复制谓词参数?

假设我们想要从ints 的向量中删除重复值.通常的解决方案是使用擦除 - 移除习语对矢量进行排序并擦除重复项.但我们需要保留不会被删除的元素的顺序,所以我们无法排序.所以有人可能会提出这样的谓词并与remove_if算法一起使用:

struct comp {
    std::set<int> s;
    comp() : s() {}
    bool operator()(int i)
    {
        return !(s.insert(i)).second;
    }
};
Run Code Online (Sandbox Code Playgroud)

但是如果出于某种原因将复制谓词对象,这将会中断,因为我们将获得该set成员的两个副本.事实上,gcc的实现remove_if确实如此:

template<typename _ForwardIterator, typename _Predicate>
    _ForwardIterator
    remove_if(_ForwardIterator __first, _ForwardIterator __last,
          _Predicate __pred)
    {

      __first = _GLIBCXX_STD_A::find_if(__first, __last, __pred);

      if(__first == __last)                             // ^^^^^ here a copy is made
        return __first;
      _ForwardIterator __result = __first;
      ++__first;
      for(; __first != __last; ++__first)
        if(!bool(__pred(*__first)))
          {
            *__result = _GLIBCXX_MOVE(*__first);
            ++__result;
          }
      return __result;
    }
Run Code Online (Sandbox Code Playgroud)

解决方法是使 …

c++ g++ functor stl-algorithm

3
推荐指数
1
解决办法
536
查看次数

您如何在逻辑或部分情况下获得开关声明?

如果你有一个switch语句,并希望在值为一个值另一个值时运行某些代码,你是如何做到的?以下代码始终为默认情况.

#include <iostream>
using namespace std;

int main()
{
    int x = 5;
    switch(x)
    {
        case 5 || 2:
            cout << "here I am" << endl;
            break;
        default:
            cout << "no go" << endl;
    }

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

c++ switch-statement logical-operators

3
推荐指数
2
解决办法
9084
查看次数

使用typedef作为变量名称不会产生任何错误

考虑到这种数据结构:

typedef struct {
    float x;
    float y;
} point;
Run Code Online (Sandbox Code Playgroud)

我正在使用此功能来置换坐标:

point permute(point M)
{
    point N;
    N.x = M.y;
    N.y = M.x;
    return N;
}
Run Code Online (Sandbox Code Playgroud)

为什么用名称(point)声明一个typedef没有给出任何错误的变量?

int main(void)
{
point A;
point B;
int point = 7;

A.x = 0;
A.y = 1;
B = permute(A);

printf("A (%.2f, %.2f)\n", A.x, A.y);
printf("B (%.2f, %.2f)\n", B.x, B.y);
printf("point = %d\n", point);

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

输出:http://ideone.com/wCxbjD

A (0.00, 1.00)
B (1.00, 0.00)
point = …
Run Code Online (Sandbox Code Playgroud)

c c++ data-structures

3
推荐指数
1
解决办法
116
查看次数

按返回类型和参数重载

是有效的

int func();
float func(int x);
Run Code Online (Sandbox Code Playgroud)

我知道只有返回类型没有模板才能重载,但这是否有效?

c++

2
推荐指数
1
解决办法
111
查看次数

插入多重集:在该值的第一次出现之前而不是在最后一次出现之后

如标题所述,multiset在所有相同值的范围的末尾插入一个值。

(例如:在一个多重插入2 1,2,2,3使得它1,2,2,/*new*/ 2,3)。

如何获得在所有相同值范围的开头插入的新值?

(例如:在多集中插入2 1,2,2,3应该使1,/*new*/ 2,2,2,3

c++ stl multiset

2
推荐指数
1
解决办法
72
查看次数