小编Jar*_*ock的帖子

如何从类中获取成员函数的返回类型?

以下程序产生编译错误clang,但它传递给其他编译器:

#include <utility>

struct foo
{
  auto bar() -> decltype(0)
  {
    return 0;
  }

  using bar_type = decltype(std::declval<foo>().bar());
};

int main()
{
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang 收益率:

$ clang -std=c++11 clang_repro.cpp 
clang_repro.cpp:10:48: error: member access into incomplete type 'foo'
  using bar_type = decltype(std::declval<foo>().bar());
                                               ^
clang_repro.cpp:3:8: note: definition of 'foo' is not complete until the closing '}'
struct foo
       ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

这个程序是非法的,如果是的话,有没有正确的方法来定义foo::bar_type

clang 细节:

$ clang --version
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM …
Run Code Online (Sandbox Code Playgroud)

c++ clang return-type-deduction

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

为什么我不能将lambda传递给这个带有std :: function的函数?

以下程序是非法的,我想了解原因:

#include <functional>
#include <iostream>

template<typename Result, typename Arg>
void deduce(std::function<Result(Arg)> f)
{
  std::cout << "Result: " << typeid(Result).name() << std::endl;
  std::cout << "Arg: " << typeid(Arg).name() << std::endl;
}


int main()
{
  auto f = [](int x)
  {
    return x + 1;
  };

  deduce(f);

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

clang的输出:

$ clang -std=c++11 test.cpp 
test.cpp:48:3: error: no matching function for call to 'deduce'
  deduce(f);
  ^~~~~~
test.cpp:26:6: note: candidate template ignored: could not match 'function<type-parameter-0-1 (type-parameter-0-0)>' against '<lambda at test.cpp:34:13>'
void …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

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

包含lambda的类型被分配后会发生什么?

假设我有某种类型包装函数,也许是lambda函数:

template<typename Function>
  struct my_struct
{
  Function f;

  my_struct(const Function &f) : f(f) {}
};
Run Code Online (Sandbox Code Playgroud)

分配此类型的实例时会发生什么?我的理解是lambdas是不可变的,并删除了赋值运算符.

然而,当我在下面的代码片段中分配这种类型的对象时,不会发出错误:

// a structure which contains a function;
// possibly a lambda function
template<typename Function>
  struct my_struct
{
  Function f;

  my_struct(const Function &f) : f(f) {}

  // XXX adding this assignment operator causes an error
  //my_struct &operator=(const my_struct &other)
  //{
  //  f = other.f;
  //  return *this;
  //}
};

template<typename Function>
my_struct<Function> make_struct(const Function &f)
{
  return my_struct<Function>(f);
}

int main()
{
  // create …
Run Code Online (Sandbox Code Playgroud)

c++ lambda

10
推荐指数
1
解决办法
3196
查看次数

如何检查下标运算符的存在?

我想编写一个类型特征,它使用SFINAE来检查类型是否存在下标表达式.下面的初始尝试似乎在下标表达式可行时起作用,但在括号运算符不存在时不起作用.

#include <iostream>
#include <vector>
#include <cassert>

template<class T, class Index>
struct has_subscript_operator_impl
{
  template<class T1,
           class Reference = decltype(
             (*std::declval<T*>())[std::declval<Index>()]
           ),
           class = typename std::enable_if<
             !std::is_void<Reference>::value
           >::type>
  static std::true_type test(int);

  template<class>
  static std::false_type test(...);

  using type = decltype(test<T>(0));
};


template<class T, class Index>
using has_subscript_operator = typename has_subscript_operator_impl<T,Index>::type;

struct doesnt_have_it {};

struct returns_void
{
  void operator[](int) {}
};

struct returns_int
{
  int operator[](int) { return 0; }
};

int main()
{
  std::cout << "has_subscript_operator<doesnt_have_it,int>: " << has_subscript_operator<doesnt_have_it,int>::value << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae type-traits c++11

10
推荐指数
1
解决办法
870
查看次数

如何在编译时推导出两种类型共有的继承树的根(如果存在)?

我有一个问题,我需要发现两种类型的共同祖先(有一个或零基类),如果它存在.是否有可能构建一个类型特征来解决这个问题?在代码中:

template<typename T1, typename T2>
  struct closest_common_ancestor
{
  typedef XXX type;  // what goes here?
};
Run Code Online (Sandbox Code Playgroud)

给出以下类型:

struct root {};
struct child1 : root {};
struct child2 : root {};
struct child3 : child2 {};
struct unrelated {};
Run Code Online (Sandbox Code Playgroud)

closest_common_ancestor 会导致以下类型:

closest_common_ancestor<root, child1>::type == root
closest_common_ancestor<child1, child2>::type == root
closest_common_ancestor<child3, child1>::type == root
closest_common_ancestor<child3, child2>::type == child2
closest_common_ancestor<unrelated, child1>::type == error
Run Code Online (Sandbox Code Playgroud)

我相信我可以解决这个问题,如果我可以检查一个类型是零还是一个基类,如果是,那么,该类型的名称.这可能吗?

c++ template-meta-programming

9
推荐指数
1
解决办法
243
查看次数

C++ Concepts TS是否支持多个参数包?

在C++ 14中,无法使用多个参数包调用函数模板:

#include <future>

template<class... Futures, class... Incrementables>
void foo(Futures&... futures, Incrementables... incrementables)
{
}

int main()
{
  std::future<int> a, b;
  int x, y;

  // ERROR
  foo(a, b, x, y);

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

因为不清楚第一个参数包的结束位置和第二个参数包的开始位置,所以foo如果没有程序员提供的附加信息,则无法调用.

但是,似乎两个参数包原则上可以消除歧义,给出适当的概念FutureIncrementable.

即将推出的C++ Concepts技术规范的任何功能是否会放宽这些限制并允许调用具有多个参数包的函数模板?

c++ variadic-templates c++-concepts

9
推荐指数
1
解决办法
325
查看次数

为什么不使用std :: is_constructible编译?

我的容器的一个构造函数默认构造一个分配器作为默认参数值:

template<class T, class Allocator>
struct my_container
{
  my_container(int n, Allocator alloc = Allocator()) {}
};
Run Code Online (Sandbox Code Playgroud)

据推测,只有在Allocator默认构造时才启用此构造函数.

我想测试一下std::is_constructible,这个构造函数是否可以与一个不是默认构造的分配器一起使用:

template<class T>
struct my_not_default_constructible_allocator
{
  // no default ctor
  my_not_default_constructible_allocator(int) {}
};
Run Code Online (Sandbox Code Playgroud)

但是,当我申请时std::is_constructible,我得到一个编译时错误,而不是false,这是我所期望的:

#include <type_traits>

template<class T, class Allocator>
struct my_container
{
  my_container(int n, Allocator alloc = Allocator()) {}
};

template<class T>
struct my_not_default_constructible_allocator
{
  // no default ctor
  my_not_default_constructible_allocator(int) {}
};

int main()
{
  bool result = std::is_constructible<my_container<int, my_not_default_constructible_allocator<int>>, int>::value;

  return …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae type-traits

9
推荐指数
1
解决办法
215
查看次数

为什么std :: allocator :: construct和std :: allocator :: destroy模板化元素类型?

std::allocatorconstructdestroy成员函数上构造元素的类型参数化:

template<class T>
  class allocator
{
  public:
    typedef T value_type;
    typedef T* pointer;

    template<class U, class... Args>
      void construct(U *p, Args&&... args);

    template<class U>
      void destroy(U *p);

  ...
};
Run Code Online (Sandbox Code Playgroud)

这是什么理由?为什么他们不采取value_type*pointer?似乎allocator<T>应该只知道如何构造或销毁类型的对象T.

c++ allocation allocator c++11

8
推荐指数
1
解决办法
1072
查看次数

是否可以在语言链接上专门化模板?

函数的语言链接是其类型的一部分:

7.5.1 ISO C++标准的[dcl.link]:

所有函数类型,函数名和变量名的默认语言链接是C++语言链接.具有不同语言链接的两种函数类型是不同的类型,即使它们在其他方面是相同的.

是否可以在函数指针的链接类型上专门化模板,或者在编译时内省函数指针的类型以确定其链接?

这第一次尝试似乎不合法:

#include <iostream>
#include <typeinfo>

struct cpp {};
struct c {};

extern "C++" void foo()
{
  std::cout << "foo" << std::endl;
}

extern "C" void bar()
{
  std::cout << "bar" << std::endl;
}

template<typename> struct linkage;

template<>
  struct linkage<void(*)()>
{
  typedef cpp type;
};

template<>
  struct linkage<extern "C" void(*)()>
{
  typedef c type;
}


int main()
{
  std::cout << "linkage of foo: " << typeid(linkage<decltype(&foo)>::type).name() << std::endl;
  std::cout << "linkage of bar: " << …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae linkage c++11

8
推荐指数
1
解决办法
270
查看次数

如何避免在thrust :: device_vector中默认构造元素?

  1. 似乎在创建一个新的Thrust向量时,默认情况下所有元素都是0 - 我只是想确认这种情况总是如此.

  2. 如果是这样,是否还有一种方法绕过负责此行为的构造函数以获得额外的速度(因为对于某些向量,我不需要它们具有初始值,例如,如果它们的原始指针作为输出传递给CUBLAS) ?

c cuda gpgpu thrust

8
推荐指数
1
解决办法
545
查看次数