小编Jar*_*ock的帖子

为什么这个调用swap()模棱两可?

以下程序

#include <algorithm>
#include <utility>
#include <memory>

namespace my_namespace
{


template<class T>
void swap(T& a, T& b)
{
  T tmp = std::move(a);
  a = std::move(b);
  b = std::move(tmp);
}

template<class T, class Alloc = std::allocator<T>>
class foo {};

}

int main()
{
  my_namespace::foo<int> *a, *b;

  using my_namespace::swap;

  swap(a,b);

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

导致两者g++clang在我的系统上发出以下编译器错误:

$ clang -std=c++11 swap_repro.cpp -I.
swap_repro.cpp:28:3: error: call to 'swap' is ambiguous
  swap(a,b);
  ^~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/algorithmfwd.h:571:5: note: candidate function [with _Tp = my_namespace::foo<int, std::allocator<int> > …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces class-template name-lookup argument-dependent-lookup

23
推荐指数
2
解决办法
1643
查看次数

给定传递给它的参数类型,如何确定函数参数的类型?

我需要一个类型特征,它将根据仿函数的operator()类型和传递给它的参数类型报告仿函数参数的类型.基本上,我需要准确确定将参数传递给仿函数时转换为什么类型.为简单起见,我们假设我只对operator()一个参数感兴趣(可能模板化,可能过载).不幸的是,我只限于c ++ 03.可以吗?如果没有,那么c ++ 11怎么样?

这是一个例子:

#include <cassert>
#include <type_traits>

template<typename Functor, typename Argument>
  struct parameter_type
{
  // what goes here?
  typedef ... type;
};

struct takes_float_cref
{
  void operator()(const float &);
};

int main()
{
  // when calling takes_float_cref::operator() with an int,
  // i'd expect a conversion to const float &
  assert(std::is_same(parameter_type<takes_float_cref, int>::type, const float &>::value);

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

一个相关的问题(答案并不能满足我的需要)给出了需要这样一个特征的背景.我已经对ideone进行了进一步的单元测试.

c++ templates parameter-passing c++11

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

在解析分配给默认参数值的重载函数时,会考虑哪些函数集?

考虑下面的函数bar,其参数具有从重载调用初始化的默认值foo:

#include <iostream>

int foo(int x)
{
  std::cout << "foo(int)" << std::endl;
  return 0;
}

template<typename T>
void bar(T a, int x = foo(T(0))) {}

double foo(double x)
{
  std::cout << "foo(double)" << std::endl;
  return 0;
}

int main()
{
  bar<int>(1);
  bar<double>(1);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我希望这个程序输出

foo(int)
foo(double)
Run Code Online (Sandbox Code Playgroud)

对应于foobar实例化时可见的两个重载.

相反,当编译时g++-4.6,输出是

$ g++-4.6 -std=c++0x test.cpp; ./a.out 
foo(int)
foo(int)
Run Code Online (Sandbox Code Playgroud)

在实现与正常重载分辨率不同的默认参数值时是否考虑了过载集?这种情况是在ISO C++标准中描述的吗?

c++ overloading

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

如何构建编译时键/值存储?

我有一个问题,我需要在编译时将一个整数映射到另一个整数.基本上,我需要编译时相当于std::map<int,int>.如果在地图中找不到某个键,我想返回一个默认值.

我想使用的界面:

template<unsigned int default_value,
         unsigned int key0, unsigned int value0,
         unsigned int key1, unsigned int value1,
         ...>
struct static_map
{
  ...
};

template<unsigned int key, typename StaticMap>
struct lookup
{
  static unsigned int value = ...
};
Run Code Online (Sandbox Code Playgroud)

lookup返回与相关联的值keyStaticMap.如果key未找到,则default_value返回.

在一般情况下,键/值对的数量将被限制一些> 2.什么是打造最好的方式来界定static_maplookup

我还要提一下,我仅限于使用C++ 03语言结构,因此没有C++ 11,也没有外部库依赖.


这是我得到的解决方案,受到nm和DyP的答案的启发:

#include <iostream>

template<unsigned int k, unsigned int v>
struct key_value
{
  static const unsigned int key = k;
  static const …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming

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

如何创建类型列表的笛卡尔积?

我想使用可变参数模板创建类型列表的交叉产品.

这是我到目前为止所拥有的:

#include <iostream>
#include <typeinfo>
#include <cxxabi.h>

template<typename...> struct type_list {};

template<typename T1, typename T2> struct type_pair {};

template<typename T, typename... Rest>
  struct row
{
  typedef type_list<type_pair<T,Rest>...> type;
};

template<typename... T>
  struct cross_product
{
  typedef type_list<typename row<T,T...>::type...> type;
};

int main()
{
  int s;
  typedef cross_product<int, float, short>::type result;
  std::cout << abi::__cxa_demangle(typeid(result).name(), 0, 0, &s) << std::endl;

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

该计划输出:

$ g++ -std=c++0x cross_product.cpp ; ./a.out 
type_list<type_list<type_pair<int, int>, type_pair<int, float>, type_pair<int, short> >, type_list<type_pair<float, int>, type_pair<float, float>, type_pair<float, …
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates c++11

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

如何在编译时检查表达式是非法的?

我的应用程序中有一个问题,我想声明函数应用程序将被编译器拒绝.有没有办法用SFINAE来检查?

例如,假设我想验证std::transformconst范围是违法的.这是我到目前为止所拥有的:

#include <algorithm>
#include <functional>
#include <iostream>

namespace ns
{

using std::transform;

template<typename Iterator1, typename Iterator2, typename UnaryFunction>
  struct valid_transform
{
  static Iterator1 first1, last1;
  static Iterator2 first2;
  static UnaryFunction f;

  typedef Iterator2                   yes_type;
  typedef struct {yes_type array[2];} no_type;

  static no_type transform(...);

  static bool const value = sizeof(transform(first1, last1, first2, f)) == sizeof(yes_type);
};

}

int main()
{
  typedef int *iter1;
  typedef const int *iter2;
  typedef std::negate<int> func;

  std::cout << "valid transform compiles: " << …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae type-traits c++-concepts

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

为什么缺少std :: uninitialized_move?

C++ 11标准库包括以下相关算法:

template <class InputIterator, class ForwardIterator>
  ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
                                     ForwardIterator result);

template <class ForwardIterator, class T>
  void uninitialized_fill(ForwardIterator first, ForwardIterator last,
                          const T& x);

template<class InputIterator, class OutputIterator>
  OutputIterator copy(InputIterator first, InputIterator last,
                      OutputIterator result);

template<class ForwardIterator, class T>
  void fill(ForwardIterator first, ForwardIterator last, const T& value);

template<class InputIterator, class OutputIterator>
  OutputIterator move(InputIterator first, InputIterator last,
                      OutputIterator result);
Run Code Online (Sandbox Code Playgroud)

没有标准uninitialized_move算法.这是疏忽还是设计?

如果是设计,理由是什么?

c++ stl c++11

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

如何分配与std :: future关联的存储?

获得的一种方法std::future是通过std::async:

int foo()
{
  return 42;
}

...

std::future<int> x = std::async(foo);
Run Code Online (Sandbox Code Playgroud)

在这个例子中,如何x分配异步状态的存储,以及哪个线程(如果涉及多个线程)负责执行分配?此外,客户std::async是否可以控制分配?

对于情况下,我看到一个构造函数std::promise可能会收到一个分配器,但如果它是可以自定义的配置,目前还不清楚我std::future的水平std::async.

c++ asynchronous future c++-standard-library c++11

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

避免标准容器中元素的默认构造

我有兴趣构建一个uninitialized_vector容器,它在语义上std::vector与警告相同,否则将使用无参数构造函数创建的新元素将在没有初始化的情况下创建.我主要是想避免将POD初始化为0. 据我所知,通过std::vector与一种特殊的分配器结合,无法实现这一点.

我想以同样的方式构建我的容器std::stack,它适应用户提供的容器(在我的情况下std::vector).换句话说,我想避免重新实现整体,std::vector而是围绕它提供一个"立面".

有没有一种简单的方法来控制"外部"的默认构造std::vector


这是我到达的解决方案,这启发了Kerrek的答案:

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
#include <cassert>

// uninitialized_allocator adapts a given base allocator
// uninitialized_allocator's behavior is equivalent to the base
// except for its no-argument construct function, which is a no-op
template<typename T, typename BaseAllocator = std::allocator<T>>
  struct uninitialized_allocator
    : BaseAllocator::template rebind<T>::other
{
  typedef typename BaseAllocator::template rebind<T>::other super_t;

  template<typename U>
    struct rebind
  {
    typedef uninitialized_allocator<U, BaseAllocator> …
Run Code Online (Sandbox Code Playgroud)

c++ stl initialization

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

在什么情况下会调用类型的转换运算符?

考虑一种类型bar,它具有用户定义的转换运算符,类型为bar:

struct bar
{
  operator bar & ();
  operator const bar & () const;
};
Run Code Online (Sandbox Code Playgroud)

这些转换什么时候应用?而且,如果这些运营商是deleted什么意味着什么呢?这两种功能都有任何有趣的用途吗?

以下程序似乎不适用于任何转换:

#include <iostream>

struct bar
{
  operator bar & ()
  {
    std::cout << "operator bar &()" << std::endl;
    return *this;
  }

  operator const bar & () const
  {
    std::cout << "operator const bar &() const" << std::endl;
    return *this;
  }
};

void foo(bar x)
{
}

int main()
{
  bar x;

  bar y = x;         // copy, no …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading

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