小编Mor*_*enn的帖子

C++ 11:将std :: is_pointer扩展为std :: shared_ptr

我认为std::is_pointer在C++ 11中重载std::shared_ptr<T>也会产生正确,因为后者的表现非常像T*.

#include <type_traits>

namespace std {

template <typename T> struct is_pointer<shared_ptr<T>> : std::true_type {};
template <typename T> struct is_pointer<shared_ptr<T const>> : std::true_type {};

}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么这个重载还没有包含在标准实现中.我忽略了一个陷阱吗?

作为替代方案,当然可以引入新的特征is_shared_ptr<T>.

实际上,我首先尝试了以下代码:

template <typename T> 
struct is_pointer<shared_ptr<typename std::remove_cv<T>::type>>
  : std::true_type 
{};
Run Code Online (Sandbox Code Playgroud)

由于没有使用GCC 4.7编译

error: template parameters not used in partial specialization:
error:         ‘T’
Run Code Online (Sandbox Code Playgroud)

c++ templates shared-ptr type-traits c++11

13
推荐指数
3
解决办法
4262
查看次数

C++初始化列表 - 我不明白

在Effective C++中,据说初始化列表中的数据元素需要按其声明的顺序列出.进一步说,对此的推理是数据元素的析构函数以其构造函数的相反顺序被调用.

但我只是看不出这可能是个问题......

c++ initialization-list

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

当试图用另一个lambda组成一个curried lambda时出乎意料的结果

我正在玩C++ 11 lambdas,并试图模仿D编程语言functional模块中的一些函数.我实际上是想实现currycompose.这是main我想要工作的:

int main()
{
    auto add = [](int a, int b)
    {
        return a + b;
    };
    auto add5 = curry(add, 5);

    auto composed = compose(add5, add);
    // Expected result: 25
    std::cout << composed(5, 15) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

问题是我从g ++和clang ++得不到相同的结果.我明白了:

  • 35与g ++ 4.8.1
  • 25与g ++ 4.8.2
  • 25与g ++ 4.9
  • 32787与clang ++ 3.5(与Coliru一起使用的主干)

g ++ 4.8.2和4.9给出了预期的结果.从g ++ 4.8.1和clang 3.5获得的结果不依赖于传递给的值curry.我首先想到这可能是一个编译器错误,但更可能是我的代码中有错误.


这是我的实现curry:

template<typename Function, typename First, std::size_t... …
Run Code Online (Sandbox Code Playgroud)

c++ lambda indices c++11

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

MinGW GCC 4.9.1和浮点确定性

我写了一个小程序来计算3坐标向量的欧几里德范数.这里是:

#include <array>
#include <cmath>
#include <iostream>

template<typename T, std::size_t N>
auto norm(const std::array<T, N>& arr)
    -> T
{
    T res{};
    for (auto value: arr)
    {
        res += value * value;
    }
    return std::sqrt(res);
}

int main()
{
    std::array<double, 3u> arr = { 4.0, -2.0, 6.0 };
    std::cout << norm(arr) - norm(arr) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

在我的电脑上打印-1.12323e-016.


我知道浮点类型应该小心处理.但是,我认为浮点运算至少在某种程度上是确定性的.这篇关于浮点确定性的文章指出:

保证的一些事情是加法,减法,乘法,除法和平方根的结果.这些操作的结果保证是正确舍入的精确结果(稍后会详细说明),因此如果您提供相同的输入值,具有相同的全局设置和相同的目标精度,则可以保证相同的结果.

如您所见,此程序对浮点值执行的唯一操作是加法,减法,乘法和平方根.如果我相信我上面引用的文章,考虑到它在单个线程中运行并且我不改变舍入模式或其他浮点相关的东西,我认为那norm(arr) - norm(arr)将是0因为我对相同的值执行完全相同的操作两次.

我的假设是错误的,或者这是编译器在IEEE浮点数学方面不严格符合的情况?我目前使用的MinGW-W64 GCC 4.9.1的32位(我试图从每一个优化级别-O0-O3).显示与MinGW-W64 GCC 4.8.x相同的程序 …

c++ floating-point mingw-w64 c++11 gcc4.9

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

如何使用函数指针noreturn?

我在C11写一个bootloader.当引导加载程序需要将控制转移到固件时,它会在预定义的内存地址读取一个函数指针并调用它.代码如下所示:

typedef void (FirmwareBootFn)(void);

typedef struct
{
    uint32_t stackPointer;
    FirmwareBootFn* programCounter;
}
FirmwareBootControl;

static FirmwareBootControl g_bootControl __attribute__ ((section (".boot_control")));

void
Firmware_boot( void )
{
    setStackPointer( g_bootControl.stackPointer );
    g_bootControl.programCounter();
}
Run Code Online (Sandbox Code Playgroud)

函数Firmware_boot()永远不会返回,因此将其声明为noreturn:

#include <stdnoreturn.h>

noreturn void
Firmware_boot( void );
Run Code Online (Sandbox Code Playgroud)

但我需要声明FirmwareBootFn,noreturn以避免编译器抱怨Firmware_boot()可能返回.

我尝试(可能)noreturntypedef没有任何结果的情况下的每个排列.另外我明白属性不能在中设置,typedef因为它不是类型的一部分.

有没有办法把我标记Firmware_boot()noreturn避免警告(没有作弊警告抑制:-))?

c c11 noreturn

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

在C++ 11中确定泛型返回类型时出错

在C++ 14应用程序的上下文中,我使用了一个可以恢复如下的方案(最小可重复性测试):

template <class Container>
struct LocateFunctions {    
  auto get_it() const // <-- here is the problem
  {
    auto ret = typename Container::Iterator();
    return ret;
  }
};

template <typename T>
struct A : public LocateFunctions<A<T>> {    
  struct Iterator {};
};

int main() {  
  A<int> a;
}
Run Code Online (Sandbox Code Playgroud)

这种方法在C++ 14中使用GCC和Clang编译器进行编译和运行.

现在我想将我的应用程序迁移到Windows,为此我正在使用MinGW.不幸的是,它的最新版本带来了GCC 4.9,它不能编译C++ 14.这似乎不是一个严重的问题,因为我可以在C++ 11中重写C++ 14结构.所以,我重写get_it()方法如下:

typename Container::Iterator get_it() const
{ 
  auto ret = typename Container::Iterator();
  return ret;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是它没有编译.两个编译器都会产生以下错误:

error: no type named ‘Iterator’ in ‘struct A<int>’
   typename Container::Iterator get_it() …
Run Code Online (Sandbox Code Playgroud)

c++ templates name-lookup c++11 c++14

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

std :: map ::在C++中插入更改17

我看到insert的方法std::map,并std::unordered_map打算从改变

template<class P> std::pair<iterator,bool> insert(P&& value); (C++11)
Run Code Online (Sandbox Code Playgroud)

std::pair<iterator,bool> insert(value_type&& value);  (C++17)
Run Code Online (Sandbox Code Playgroud)

但是,对于这些容器,value_typestd::pair<A const, int>.这里有两个问题:

  1. 为何如此改变?有什么好处?
  2. 如何在插入时移动密钥?C++ 11版本接受任何东西(对Pis 的约束default_constructible<value_type, P&&>),然后std::pair<A, int>- 这是大多数时候这个参数的类型,因为它是返回的std::make_pair- 并且可以调用它的移动构造函数A.但是在C++ 17版本中,这个参数被转换为value_type,其中A是const,然后是不可移动的.如果我没有忽略某些东西,则必须复制.或者C++ 17也改变了这方面的任何东西?

谢谢!

c++ stl move c++11 c++17

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

为什么汽车的推断方式不同?

int main(){
    int x{};
    auto x2 = x;
    auto x3{x};

    static_assert(is_same<int, decltype(x)>::value, "decltype(x) is the same as int");
    static_assert(is_same<int, decltype(x2)>::value, "decltype(x2) is the same as int");
    static_assert(is_same<int, decltype(x3)>::value, "decltype(x3) is the same as int"); // Error here.
}
Run Code Online (Sandbox Code Playgroud)

此代码无法使用gcc 4.8.0进行编译.我甚至没猜到它的类型decltype(x3).它是什么?为什么行为不同?

c++ type-inference c++11

11
推荐指数
2
解决办法
392
查看次数

如何在Python ctypes中处理C++返回类型std :: vector <int>?

我找不到ctypes如何弥合std::vector和Python 之间的差距; 没有在互联网上提到的组合.这是不好的做法,它不存在还是我错过了什么?

C++:xxx.cpp

#include <fstream>
#include <string>
using namespace std;
extern "C" std::vector<int> foo(const char* FILE_NAME)
{
    string line;
    std::vector<int> result;
    ifstream myfile(FILE_NAME);
    while (getline(myfile, line)) {
      result.push_back(1);
    }

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

Python: xxx.py

import ctypes
xxx = ctypes.CDLL("./libxxx.so")
xxx.foo.argtypes = ??????
xxx.foo.restype = ??????
Run Code Online (Sandbox Code Playgroud)

c++ python ctypes

11
推荐指数
2
解决办法
9838
查看次数

SFINAEd-out函数是否会影响基类中显式导入的重载

在遇到另一个设计的问题之后,我决定make make一个包装类来向基类的某些成员函数添加重载,当且仅当基类中不存在可行的重载时.基本上,这是我想要做的:

template<typename T>
struct wrapper: T
{
    using T::foo;

    template<typename Arg>
    auto foo(Arg) const
        -> std::enable_if_t<not std::is_constructible<Arg>::value, bool>
    {
        return false;
    }
};

struct bar
{
    template<typename Arg>
    auto foo(Arg) const
        -> bool
    {
        return true;
    }
};
Run Code Online (Sandbox Code Playgroud)

在这个简单的例子中,只有当基类中的那个不可行时才wrapper添加一个重载foo(我简化std::enable_if为最简单的东西;原始的一个涉及检测习语).但是,g ++和clang ++不同意.请考虑以下事项main:

int main()
{
    assert(wrapper<bar>{}.foo(0));
}
Run Code Online (Sandbox Code Playgroud)

g ++没关系:foofrom wrapper<bar>是SFINAEd,所以它使用的是bar相反的.在另一方面,铛++似乎假定wrapper<bar>::foo 永远的阴影bar::foo,即使SFINAEd出来.这是错误消息:

main.cpp:30:26: error: no matching member function for call to 'foo' …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae shadowing language-lawyer c++11

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