小编fra*_*sco的帖子

错误:用clang没有可行的重载,用gcc编译

下面的程序可以用 g++(版本 10.1.0)编译,但不能用 clang++(10.0.0)编译

#include <iostream>

template <typename U>
struct A { U x; };

namespace tools {
  template <typename U>
  void operator+=(A<U>& lhs, const A<U>& rhs) { lhs.x += rhs.x; }
}

namespace impl {
  template <typename U = int>
  void f() {
    A<U> a{3};
    A<U> b{2};
    a += b;
    std::cout << a.x << std::endl;
  }
}

namespace impl {
  using namespace tools;
}

int main()
{
  impl::f();
}
Run Code Online (Sandbox Code Playgroud)

错误是:

name.cpp:16:7: error: no viable overloaded '+='
    a += b; …
Run Code Online (Sandbox Code Playgroud)

c++ templates namespaces language-lawyer

16
推荐指数
2
解决办法
922
查看次数

传递给协程的临时人员何时被销毁?

我对传递给协程任务的临时人员的一生感到困惑。考虑以下示例:

cppcoro::task<> UseObject(Object const& object);

cppcoro::task<> CallUseObject() {
    co_await UseObject(Object()); // is this valid?
}
Run Code Online (Sandbox Code Playgroud)

如果这些函数返回void,则Object()传递给的UseObject将在分号处被破坏(即在UseObject完成后)。但是,我不确定协程是否同样适用。通过引用将临时传递给例程是否安全?如果不是在分号上,临时人员什么时候会被销毁?

此外,作为健全性检查,是否总是可以安全地编写:

cppcoro::task<> CallUseObject() {
    Object stayingalive;
    co_await UseObject(stayingalive);
}
Run Code Online (Sandbox Code Playgroud)

因为staying_aliveco_await完成后被销毁了?

c++ c++20 c++-coroutine

14
推荐指数
1
解决办法
289
查看次数

C ++通用编译时循环

在某些情况下,for在编译时评估/展开循环可能是有用/必要的。例如,要遍历a的元素tuple,需要使用std::get<I>,这取决于模板int参数I,因此必须在编译时对其进行评估。使用编译递归可以解决一个特定的问题,例如此处此处以及std::tuple 此处专门讨论的问题。

但是,我对如何实现通用编译时for循环感兴趣。

以下c++17代码实现了这个想法

#include <utility>
#include <tuple>
#include <string>
#include <iostream>

template <int start, int end, template <int> class OperatorType, typename... Args>
void compile_time_for(Args... args)
{
  if constexpr (start < end)
         {
           OperatorType<start>()(std::forward<Args>(args)...);
           compile_time_for<start + 1, end, OperatorType>(std::forward<Args>(args)...);
         }    
}

template <int I>
struct print_tuple_i {
  template <typename... U>
  void operator()(const std::tuple<U...>& x) { std::cout << std::get<I>(x) …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming variadic-templates c++17 c++20

14
推荐指数
1
解决办法
1235
查看次数

c ++在有符号和无符号之间进行隐式转换的代码的安全性

根据有符号和无符号整数类型之间的隐式转换规则,这里这里讨论,当unsigned int用a 求和时int,int首先将signed 转换为a unsigned int.

例如,考虑以下最小程序

#include <iostream>

int main()
{
   unsigned int n = 2;
   int x = -1;

   std::cout << n + x << std::endl;

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

然而,程序的输出是预期的1:x首先转换为a unsigned int,并且总和n导致整数溢出,给出"正确"的答案.

在像前一个代码,如果我知道肯定n + x是积极的,我可以假设的总和unsigned int n,并int x给出了预期值?

c++

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

-O1更改浮点数学

c++当使用-O0或编译时,以下程序给出的数值不同-O1

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

int main()
{
  std::array<double, 2> v;
  v.fill(0);

  std::get<0>(v) = 0x1.5b4d3afe1f7d2p-1;
  double theta = 0x1.1aef12f82caf9p+2;

  double c = std::cos(theta);
  double s = std::sin(theta);
  double vi = c * std::get<0>(v) - s * std::get<1>(v);
  double vj = s * std::get<0>(v) + c * std::get<1>(v);
  std::get<0>(v) = vi;
  std::get<1>(v) = vj;

  std::cout << std::hexfloat;
  for (const auto& x : v)
    std::cout << x << " ";
  std::cout << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point gcc

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

Fortran 函数返回可分配数组

让我考虑一个返回一个的函数allocatable数组的函数。是否应该在赋值之前分配保存结果的数组变量(在函数外部)?

\n

例如,考虑以下程序

\n
program mem\n  implicit none\n\n  interface\n     function get_matrix() result(res)\n       real(kind=kind(0.d0)), allocatable :: res(:,:)\n     end function get_matrix\n  end interface\n  \n  real(kind=kind(0.d0)), allocatable :: w(:,:)\n\n  allocate(w(2,2)) ! Is this necessary?\n  w=get_matrix()\n  deallocate(w)\n\nend program mem\n\nfunction get_matrix() result(res)\n  real(kind=kind(0.d0)), allocatable :: res(:,:)\n\n  allocate(res(2,2))\n  res = 0.d0\n  res(1, 1) = 1.d0\n  res(2, 2) = 1.d0\nend function get_matrix\n
Run Code Online (Sandbox Code Playgroud)\n

根据thisthisres ,为 的 结果分配的数组get_matrix一旦超出范围就会被释放。

\n

w对主程序中未分配变量的赋值是否会延长结果的范围get_matrix?换句话说,如果我allocate(w(2,2))在主程序中省略,我会得到未定义的行为吗?

\n

省略allocate(w(2,2))并使用gfortran …

fortran function allocatable-array

7
推荐指数
2
解决办法
2725
查看次数

基本模板类的成员的可见性未直接继承

对模板基类成员的访问需要语法this->memberusing指令。此语法是否还会扩展到未直接继承的基本模板类?

考虑以下代码:

template <bool X>
struct A {
  int x;
};

template <bool X>
struct B : public A<X> {
  using A<X>::x; // OK even if this is commented out
};

template <bool X>
struct C : public B<X> {
  // using B<X>::x; // OK
  using A<X>::x; // Why OK?
  C() { x = 1; }
};

int main()
{
  C<true> a;

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

因为模板类的声明B包含using A<X>::x,自然衍生的模板类C可以访问x使用using …

c++ inheritance templates using-declaration language-lawyer

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

invoke_result 获取模板成员函数的返回类型

如何获取模板成员函数的结果类型?

以下最小示例说明了该问题。

#include <type_traits>

template <typename U>
struct A {
};

struct B {
   template <typename F = int>
   A<F> f() { return A<F>{}; }

   using default_return_type = std::invoke_result_t<decltype(f)>;
};

int main()
{
    B::default_return_type x{};

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

看到它在Coliru。

代码不编译,报错:

main.cpp:11:63: 错误:decltype 无法解析重载函数的地址

11 | 使用 default_return_type = std::invoke_result_t;

B::f在模板参数F设置为默认值的情况下获取类型的正确语法是什么?

c++ templates type-traits invoke-result

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

包装任意类型/非类型模板类的模板类

假设我有一个模板类base和一个wrapper包含实例化成员的类base.我想定义这样的类wrapper,它依赖于一个模板参数包,它简单地"传递"给实例化的成员base.

例如,考虑以下代码,它可以正常工作.

#include <iostream>

template <int i, int j>
struct base {
  base()
  {
    std::cout << "i is " << i;
    std::cout << " j is " << j << std::endl;
  }
};

template <int... T>
struct wrapper {
  base<T...> a;
};

int main()
{
  wrapper<2, 3> x;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

事先知道所有模板参数base都是int,我template <int...T>在声明中使用wrapper.这允许有限的灵活性,例如我可以为模板参数定义一些默认值base,而无需修改wrapper.

但是,如果base依赖型和非类型模板参数的任意波形名单上,我怎么能传递的模板参数wrapper来 …

c++ templates

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

std::bind 如何导致多次调用复制构造函数

我一直在尝试了解 std::bind 的工作原理。因此,我们要尝试不同的例子。下面是我无法理解其输出的示例程序。

版本1

class NAME
{
  public:
    void f()
    {
        std::cout<<"f"<<std::endl;
    }
    NAME()
    {
        std::cout<<"default constructor"<<std::endl;
    }
    NAME(const NAME&)
    {
        std::cout<<"copy constructor"<<std::endl;
    }
};
int main()
{
   std::cout << "Hello World" << std::endl; 
   NAME n;
   std::function<void ()> callable = std::bind(&NAME::f, n);
   
   
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述版本1的输出如下:

Hello World
default constructor
copy constructor
copy constructor
Run Code Online (Sandbox Code Playgroud)

我知道传递的参数将被复制,因此复制构造函数应该只被调用一次,但在上面的输出中复制构造函数被调用两次。为什么/怎么会发生这种情况?是否因为使用 std::bind 创建的新可调用对象将用于在 lhs 上使用 std::function 初始化另一个可调用对象?

版本2

int main()
{
   std::cout << "Hello World" << std::endl; 
   NAME n;
   std::function<void ()> callable = std::move(std::bind(&NAME::f, n));
   return …
Run Code Online (Sandbox Code Playgroud)

c++ bind stdbind auto c++11

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