小编HC4*_*ica的帖子

在其参数的结构上重载C/C++预处理器宏

我想编写一个预处理器宏,如果它的参数是带括号的标记元组,它会做一件事,如下所示:

MY_MACRO((x, y))
Run Code Online (Sandbox Code Playgroud)

如果它只是一个令牌,还有其他东西,如下所示:

MY_MACRO(x)
Run Code Online (Sandbox Code Playgroud)

那可能吗?

如何区分空格分隔的标记的数量,即MY_MACRO(x)MY_MACRO(x y)?之间?

请注意,我不是试图根据参数的数量重载 - 它在所有情况下都是一元宏.

编辑:如果他们有所帮助,我愿意使用可变参数宏

c c++ overloading c-preprocessor

6
推荐指数
1
解决办法
3973
查看次数

基于范围的循环和ADL

所述的C++ 0x标准工作草案状态(部分6.5.4)关于开始以下()和()结束,在是隐式的呼叫的范围为基础的循环:

使用参数依赖查找(3.4.2)查找'begin'和'end'.出于此名称查找的目的,名称空间std是关联的名称空间.

我读这个的方式,这意味着为begin()和end()调用设置的重载决议包括以下所有内容:

  • begin()和end()的所有重载都在使用基于范围的for循环的位置的范围内(特别是,全局命名空间中的所有重载都在范围内)
  • 命名空间std中begin()和end()的所有重载
  • 在与其参数关联的其他名称空间中的begin()和end()的所有重载

那是对的吗?

g ++ 4.6的行为似乎与这种解释不一致.对于此代码:

#include <utility>

template <typename T, typename U>
T begin(const std::pair<T, U>& p); 

template <typename T, typename U>
U end(const std::pair<T, U>& p); 

int main()
{
    std::pair<int*, int*> p;
    for (int x : p)
        ;
}
Run Code Online (Sandbox Code Playgroud)

它给出了以下错误:

adl1.cpp: In function 'int main()':
adl1.cpp:12:18: error: No match for 'begin(pair<int *, int *> &)'
adl1.cpp:12:18: candidate is:
/usr/local/lib/gcc/i686-pc-linux-
    gnu/4.6.0/../../../../include/c++/4.6.0/initializer_list:86:38: template<
        class _Tp> constexpr const _Tp * begin(initializer_list<_Tp>)
adl1.cpp:12:18: error: No …
Run Code Online (Sandbox Code Playgroud)

c++ foreach argument-dependent-lookup c++11

6
推荐指数
1
解决办法
1614
查看次数

如何在继续之前明确等待TCP ACK?

有没有办法让send()等待所有已发送的数据已被确认(或者如果已达到ACK超时则返回-1),或者是否有其他机制等待在send()之后但在做其他事情之前确认?

我使用的是标准的Unix Berkeley套接字API.

我知道我可以实现一个应用层ACK,但是当TCP的ACK很好地完成目的时,我宁愿不这样做.

c sockets tcp

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

涉及私有继承的C++编译器错误

有人可以向我解释以下编译器错误:

struct B
{
};

template <typename T>
struct A : private T
{
};

struct C : public A<B>            
{                                                                             
    C(A<B>);   // ERROR HERE
};
Run Code Online (Sandbox Code Playgroud)

指示行的错误是:

test.cpp:2:1: error: 'struct B B::B' is inaccessible
test.cpp:12:7: error: within this context
Run Code Online (Sandbox Code Playgroud)

究竟什么是难以接近的,为什么?

c++ inheritance templates compiler-errors private-inheritance

6
推荐指数
1
解决办法
274
查看次数

枚举和枚举类的链接兼容性

假设有一个使用枚举类的C++ 11 API:

// api.hpp
enum class E {A, B, C};
void f(E);
...

// api.cpp
void f(E e)
{
    if (e == E::A)
       ...
}
Run Code Online (Sandbox Code Playgroud)

现在假设我想使用这个API,但我没有C++ 11编译器.所以我:

  • 修改api.hpp枚举类并将其更改为常规枚举.
  • 编写一些包含修改后的代码,api.hpp并正常使用API​​(例如调用f).
  • 使用我的非C++ 11编译器编译此代码,并将其链接到使用C++ 11编译器编译的API实现(使用未修改的编译器api.hpp).

这似乎与海湾合作委员会有关,但一般来说是安全的,还是我玩火(ODR违规等)?

假设两个编译器在其他方面是链接兼容的,那么只有enum vs. enum类才有问题.

c++ linker abi c++11 enum-class

6
推荐指数
1
解决办法
622
查看次数

模板类型作为SWIG中的结构数据成员

我正在使用SWIG为C++库编写PHP包装器,但是我在使用具有模板类型实例的结构作为数据成员时遇到了问题.

假设我有以下头文件:

template <typename>
struct myvector
{
};

struct S
{
    myvector<int> v;
};

myvector<int> foo();
S bar();
Run Code Online (Sandbox Code Playgroud)

和接口文件:

%module test
%{
#include "test.hpp"
%}

%include "test.hpp"
%template(IntVec) myvector<int>;
Run Code Online (Sandbox Code Playgroud)

当我尝试使用直接返回的函数时myvector,它工作正常:

$v1 = test::foo();
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用返回S对象的函数,并尝试访问其类型为的数据成员时myvector:

$s = test::bar();
$v2 = $s->v;
Run Code Online (Sandbox Code Playgroud)

我在运行时收到以下错误:

PHP Fatal error:  Class 'myvectorT_int_t' not found in test.php on line 145
Run Code Online (Sandbox Code Playgroud)

我可能错过了我的界面文件,但我不知道是什么.有人可以帮忙吗?

php c++ swig templates language-binding

6
推荐指数
1
解决办法
617
查看次数

非本地C++ 11 lambdas是否存在于匿名命名空间中?

最新版本的GCC 4.8在头文件中提供以下代码:

auto L = [](){};

struct S
{
    decltype(L) m;
};
Run Code Online (Sandbox Code Playgroud)

以下警告:

test.hpp:3:8: warning: 'S' has a field 'S::m' whose type uses the anonymous namespace [enabled by default]
 struct S
        ^
Run Code Online (Sandbox Code Playgroud)

为什么编译器会考虑lambda的类型来使用匿名命名空间?我使lambda全局化,我没有在任何地方使用匿名命名空间.

更新:即使我将lambda放在显式名称空间中,compiles也会发出相同的警告,如下所示:

namespace N
{
    auto L = [](){};
}

struct S
{
    decltype(N::L) m;
};
Run Code Online (Sandbox Code Playgroud)

更新2:事实上,甚至类范围lambda都有同样的问题:

class N
{
    static constexpr auto L = [](){};
};

struct S
{
    decltype(N::L) m;
};
Run Code Online (Sandbox Code Playgroud)

c++ lambda namespaces global-variables c++11

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

实施定义的缩小转换?

C++ 11形式化了缩小转换的概念,并禁止在列表初始化中使用顶级转换.

我想知道是否给定两个类型TU,有可能它是实现定义的转换是否TU正在缩小.根据我对标准的解读,情况就是如此.这是我的推理:

  • 根据dcl.init.list(8.5.4)第7段,转换可以缩小的一种方式是,如果它是一个隐式转换,"从整数类型或无范围枚举类型到整数类型,不能代表原始值的所有值类型".
  • 考虑从unsigned int到的隐式转换long.
  • 关于的相对尺寸intlong,C++只要求sizeof(int) <= sizeof(long).
  • 考虑一个实现A,其中sizeof(int) == sizeof(long).在这个实现中,long不能代表所有的值unsigned int,所以转换会缩小.
  • 考虑一个实现B,其中sizeof(int) < sizeof(long).在此实现中,long可以表示所有值unsigned int,因此转换不会缩小.

我的分析是否正确,可以通过实现来定义转换是否正在缩小?这是可取的吗?

c++ implicit-conversion c++11 list-initialization

6
推荐指数
1
解决办法
278
查看次数

用于非类型模板参数的用例不是整数/枚举类型?

C++允许非类型模板参数为整数或枚举类型(包括布尔和字符的整数),以及指向任意类型的指针和引用.

我已经看到广泛使用的整数,布尔和枚举参数,我很欣赏它们的实用性.我甚至已经看到巧妙地使用字符参数进行字符串的编译时解析.

但我想知道什么是非类型模板参数的一些用例,它们是指针或对任意类型的引用?

c++ templates non-type

6
推荐指数
1
解决办法
590
查看次数

有没有办法推断出函数指针模板参数的值?

C++允许非类型模板参数为指针,包括函数指针,类型.最近,我问了一个问题,什么这是有用的,这是一个后续行动的答案之一.

从作为函数指针的函数参数中推导出函数指针模板参数的是否可行?例如:

using VoidFunction = void(*)();

template <VoidFunction F>
void templ(VoidFunction);

...

void func();  // a VoidFunction

...

templ<func>(func);  // works, but I have to specify the template parameter explicitly
templ(func);        //  <-- I would like to be able to do this
Run Code Online (Sandbox Code Playgroud)

有没有办法让这种演绎发生?从编译器实现者的角度来看,技术上似乎是可能的,只要函数参数可以在编译时解析为代码中的函数.

如果您想知道这背后的动机,请参阅此答案下的评论,特别是可能的实施优化std::bind().

编辑:我意识到我可以简单地删除函数参数并使用模板参数,如templ<func>().添加函数参数的唯一目的是尽量避免传递模板参数.

我想我真正想要的是,还推断出函数指针的类型,如:

template <typename Function, Function F>
void templ(/* something */);
Run Code Online (Sandbox Code Playgroud)

然后就可以打电话了

templ(func);
Run Code Online (Sandbox Code Playgroud)

要么

templ<func>();
Run Code Online (Sandbox Code Playgroud)

并且只需提及函数指针就可以推导出类型和值.

希望现在更有意义.

c++ templates non-type template-argument-deduction

6
推荐指数
1
解决办法
977
查看次数