小编dcm*_*m88的帖子

使用lambda作为非类型模板参数时为什么gcc失败?

下面的代码片段与Clang 4.0没有错误编译,但GCC 7.0会产生错误(注意使用-std = c ++ 1z标志).

using FuncT = int (*)(double);

template <FuncT FUNC>
int temp_foo(double a)
{
    return FUNC(a);
}

int foo(double a)
{
    return 42;
}

void func()
{
    auto lambda = [](double a) { return 5; };

    struct MyStruct
    {
        static int foo(double a) { return 42; }
    };

    temp_foo<foo>(3);
    temp_foo<static_cast<FuncT>(lambda)>(3);
    temp_foo<MyStruct::foo>(3);
}
Run Code Online (Sandbox Code Playgroud)

具体来说,GCC抱怨lambda和嵌套类的方法都没有链接,所以它们不能用作非类型模板参数.

至少对于lambda案例,我认为Clang是正确的(并且GCC是错误的)因为(引用cppreference,转换运算符):

此转换函数返回的值是指向具有C++语言链接的函数的指针,该函数在调用时具有与直接调用闭包对象的函数调用操作符相同的效果.

海湾合作委员会是否行为不端?

c++ lambda templates non-type c++17

15
推荐指数
1
解决办法
817
查看次数

如何处理由空模板参数包扩展引起的未使用警告?

我一直面临的一个问题是编译器抱怨未使用的变量,即使使用了变量,但它仅用于特定实例化的参数包扩展中.例如:

template <std::size_t... I>
auto func1(std::index_sequence<I...>)
{
  auto var = get_tuple();
  return func2(std::get<I>(var)...);
}

auto a = func1(std::make_index_sequence<0>());
Run Code Online (Sandbox Code Playgroud)

查看实例(尝试在第4行更改元组,在<>中添加一个int以查看警告消失).我知道我可以添加(void)var;一行来使警告消失,但对我来说感觉很脏,特别是当函数实际上只是一行时.我也不想在全球范围内禁用此警告,因为它确实提供了有时的洞察力.

此问题的类似表现形式是在lambda捕获中使用变量时.在这种情况下,gcc没有发出警告,而clang抱怨(我认为gcc从未实现过关于未使用的lambda捕获的警告):

template <std::size_t... I>
auto func1(std::index_sequence<I...>)
{
  auto var = get_tuple();
  auto my_lambda = [var](){
    return func2(std::get<I>(var)...);
  };
  return my_lambda();
}

auto a = func1(std::make_index_sequence<0>());
Run Code Online (Sandbox Code Playgroud)

铿锵的例子

gcc clang compiler-warnings variadic-templates c++11

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

g ++是否与函数模板重载行为不正常?

我从http://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading中获取了以下示例, 并且clang(3.4)似乎正好处理它,而g ++(4.8.3)给出了一个'模糊的重载'错误:

struct A {};
template<class T> struct B {
  template<class R> void operator*(R&){ cout << "1" << endl; }             // #1
};
template<class T, class R> void operator*(T&, R&) { cout << "2" << endl;}  // #2
int main() {
  A a;
  B<A> b;
  b * a; //prints 1
}
Run Code Online (Sandbox Code Playgroud)

clang正确打印1(根据cppreference预期),而g ++给出了这个错误:

test_templates.cpp: In function ‘int main()’:
test_templates.cpp:13:5: error: ambiguous overload for ‘operator*’ (operand types are ‘B<A>’ and ‘A’)
   b * a; //prints 1
     ^
test_templates.cpp:13:5: …
Run Code Online (Sandbox Code Playgroud)

c++ templates g++ clang

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

将constexpr intializer_list作为参数传递给c ++ 14

为什么这不起作用:

constexpr initializer_list<int> ilist = {1,2,3,4};
constexpr int my_min = min(ilist);
Run Code Online (Sandbox Code Playgroud)

虽然这样做:

constexpr int my_min = min({1,2,3,4});
Run Code Online (Sandbox Code Playgroud)

我在我的基础上的代码的constexpr的std :: MIN()函数,如在这里和我使用clang3.5.0编译器(G ++ 4.9.1似乎没有意识到一个constexpr的std ::分钟()).

我无法理解我得到的错误:

clang35 -stdlib=libc++ -std=c++14 test.cpp  -o test;
test.cpp:158:35: error: constexpr variable 'ilist' must be initialized by a constant expression
  constexpr initializer_list<int> ilist = {1,2,3,4};
                                  ^       ~~~~~~~~~
test.cpp:158:35: note: pointer to subobject of temporary is not a constant expression
test.cpp:158:43: note: temporary created here
  constexpr initializer_list<int> ilist = {1,2,3,4};
                                          ^
test.cpp:159:17: error: constexpr variable 'my_min' must …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++14

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

如何为类模板定义非成员运算符重载?

我有一个类模板,其构造函数采用std :: chrono :: duration,因为我希望能够使用chrono_literals来构造它.现在,我正在尝试定义非成员运算符重载,但我无法使用持续时间构造函数:

#include <chrono>
#include <iostream>

using namespace std;

template <int n> struct MyClass {
  MyClass() = default;

  template <typename REP, typename PERIOD>
  constexpr MyClass(const std::chrono::duration<REP, PERIOD> &d) noexcept
      : num(d.count()) {}

  int num = n;
};

template <int n> bool operator==(MyClass<n> lhs, MyClass<n> rhs) {
  return lhs.num == rhs.num;
}

int main(int argc, char *argv[]) {
  using namespace std::literals::chrono_literals;

  MyClass<0> m1(10ns);

  if (m1 == 10ns)
    cout << "Yay!" << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

gcc拒绝我的重载就是这个错误:

main.cpp:34:12: error: …
Run Code Online (Sandbox Code Playgroud)

c++ templates operator-overloading c++11 c++14

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

"char(&(...))[2]"的含义是什么意思?

我遇到了以下代码:

char (&f(...))[2];

我检查了它的类型(使用typeid和c ++ filt)并获得:

char (&(...)) [2]

但我无法理解这种类型.[2]是让我失望的部分.没有它,我可以在函数定义中复制类型,例如:

char (&f(...))

f与h in的类型相同(至少从typeid + c ++ filt的输出):

char& h(...)

c++

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

将pandas数据框与密钥重复项合并

我有2个数据帧,两个都有一个可能有重复的键列,但数据帧大多数都有相同的重复键.我想在这个键上合并这些数据帧,但是当这两个数据帧具有相同的重复时,这些重复项将分别合并.此外,如果一个数据帧的密钥重复多于另一个,我希望它的值可以填充为NaN.例如:

df1 = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K2', 'K2', 'K3'],
                    'A':   ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']}, 
                   columns=['key', 'A'])
df2 = pd.DataFrame({'B':   ['B0', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6'],
                    'key': ['K0', 'K1', 'K2', 'K2', 'K3', 'K3', 'K4']}, 
                   columns=['key', 'B'])

  key   A
0  K0  A0
1  K1  A1
2  K2  A2
3  K2  A3
4  K2  A4
5  K3  A5

  key   B
0  K0  B0
1  K1  B1
2  K2  B2
3  K2  B3
4  K3  B4
5  K3  B5
6 …
Run Code Online (Sandbox Code Playgroud)

python merge dataframe pandas

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

如何在CMake的用户包注册表中支持多个包版本?

我试图了解如何使用CMake 用户包注册表来支持多个构建,例如调试和发布构建。

我有一个 package1,它可以正确调用,以便它使用 CMake 的用户包注册表export(PACKAGE package1)注册构建目录。然后,我继续创建 2 个单独的构建目录,一个用于调试,一个用于发布(请注意,我将调试构建的版本设为 3.0.2000000,而发布构建的版本为 3.0.1000000,因为我希望 CMake 更喜欢我的用例中的调试版本)。正如预期的那样,每个构建都在注册表中注册了一个项目:

> ls ~/.cmake/packages/package1/
212e973d0f1858e4bdf95b9d105bed5a  78094ed9b729d420c3f782cd8e668e64
Run Code Online (Sandbox Code Playgroud)

现在,我在另一个项目 package2 中使用它,find_package(package1 3.0.740)但它只能在发布版本中找到该项目。我尝试在调用后立即检查package1_CONSIDERED_CONFIGS和,但仍然只有发布版本的配置和版本。package1_CONSIDERED_VERSIONSfind_package

package2的CMakeLists.txt文件中的代码:

SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)

message("CMAKE_FIND_PACKAGE_SORT_ORDER="
        "${CMAKE_FIND_PACKAGE_SORT_ORDER}")
message("CMAKE_FIND_PACKAGE_SORT_DIRECTION="
        ${CMAKE_FIND_PACKAGE_SORT_DIRECTION}")
find_package(package1 3.0.740)

message("Considered Configs:  ${package1_CONSIDERED_CONFIGS}")
message("Considered Versions: ${package1_CONSIDERED_VERSIONS}")
Run Code Online (Sandbox Code Playgroud)

CMake运行以上代码的结果:

cmake ../..
-- Using link pool size - 16 jobs
CMAKE_FIND_PACKAGE_SORT_ORDER=NATURAL
CMAKE_FIND_PACKAGE_SORT_DIRECTION=DEC
Considered Configs:  /path/to/package1/Release/package1Config.cmake
Considered Versions: 3.0.1000000
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?用户注册表应该如何使用?

cmake

5
推荐指数
0
解决办法
477
查看次数

简单的无锁堆栈c ++ 11

我已经看到了几个过于复杂的(在我看来很明显)在c ++中使用无锁堆栈的实现(使用像这里的标签),我想出了一个简单但仍然有效的实现.因为我无法在任何地方找到这个实现(我已经看到Push函数的实现类似于我所做的而不是Pop),我猜它在某种程度上是不正确的(很可能是ABA案例失败):

template<typename Data>
struct Element
{
  Data mData;
  Element<Data>* mNext;
};

template<typename Data>
class Stack
{
 public:
  using Obj = Element<Data>;
  std::atomic<Obj*> mHead;

  void Push(Obj *newObj)
  {
    newObj->mNext = mHead.load();
    //Should I be using std::memory_order_acq_rel below??
    while(!mHead.compare_exchange_weak(newObj->mNext, newObj));
  }

  Obj* Pop()
  {
    Obj* old_head = mHead.load();
    while (1)
    {
      if (old_head == nullptr)
        return nullptr;
      //Should I be using std::memory_order_acq_rel below??
      if(mHead.compare_exchange_weak(old_head, old_head->mNext)) ///<<< CL1
        return old_head;
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

我假设Push和Pop的调用者将负责内存分配和释放.另一种选择是制作上述Push和Pop私有方法,并使用新的公共函数来处理内存分配并在内部调用这些函数.我相信这个实现中最棘手的部分是我用"CL1"标记的行.我认为它是正确的并且仍然适用于ABA案例的原因如下:

让我们说ABA案件确实发生了.这意味着"CL1"处的mHead将等于old_head,但是它们指向的对象实际上与我将mHead分配给它时最初指向的old_head不同.但是,我认为即使它是一个不同的对象我们仍然可以,因为我们知道它是一个有效的"头".old_head指向与mHead相同的对象,因此它是堆栈的有效头部,这意味着old_head-> mNext是有效的下一个头.因此,将mHead更新为old_head-> mNext仍然是正确的!

总结一下:

  1. 如果mHead!= old_head(另一个线程抢占我们并更改了mHead) …

c++ stack multithreading lock-free c++11

3
推荐指数
1
解决办法
2599
查看次数

为什么2个不同的python lambda具有相同的字节码?

我看到一些我不理解的行为.我认为python函数的字节码是为了产生结果而被执行的,但是在这里我有2个不同的lambda函数,它们具有相同的字节码,但显然做了不同的事情.怎么会这样?

a = lambda x: x+4
b = lambda y: y+3
print('a = ', a.__code__.co_code)
print('b = ', b.__code__.co_code)
print(a(1), b(1))
Run Code Online (Sandbox Code Playgroud)

生成此输出:

a =  b'|\x00\x00d\x01\x00\x17S'
b =  b'|\x00\x00d\x01\x00\x17S'
5 4
Run Code Online (Sandbox Code Playgroud)

python lambda cpython

3
推荐指数
1
解决办法
114
查看次数

如何使用ctest将参数传递给memcheck?

我想从命令行使用 ctest 用 memcheck 运行我的测试并传入 memcheck 命令的参数。

我可以运行ctest -R my_test来运行我的测试,我什ctest -R my_test -T memcheck至可以通过 memcheck运行来运行它。

但我似乎无法找到一种方法将参数传递给该 memcheck 命令,例如--leak-check=full--suppressions=/path/to/file

在阅读了 ctest 的文档后,我尝试将-D选项与CTEST_MEMCHECK_COMMAND_OPTIONS和 一起使用MEMCHECK_COMMAND_OPTIONS。我也尝试将这些设置为环境变量。我的尝试都没有产生任何不同的测试命令。总是如此:

Memory check command: /path/to/valgrind "--log-file=/path/to/build/Testing/Temporary/MemoryChecker.7.log" "-q" "--tool=memcheck" "--leak-check=yes" "--show-reachable=yes" "--num-callers=50"
Run Code Online (Sandbox Code Playgroud)

如何从 ctest 命令行控制 memcheck 命令?

command-line valgrind cmake ctest memcheck

3
推荐指数
1
解决办法
2012
查看次数

表达概念中数据成员的概念要求的最佳方式是什么?

为该类型的数据成员定义具有嵌套概念要求的概念的最佳方法是什么?沿着这些路线的东西:

template<typename T>
concept MyConcept = requires(T a) {    
    {a.something} -> std::integral;
};
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为a.something它被作为参考 ( delctype((a.something)))选取。我想出的最好的作品是这样的东西,它强制一个右值:

constexpr auto copy = [](auto value) { return value; };

template<typename T>
concept MyConcept = requires(T a) {    
    {copy(a.something)} -> std::integral;
};
Run Code Online (Sandbox Code Playgroud)

我有更好的选择吗?

c++ c++-concepts c++20

3
推荐指数
1
解决办法
101
查看次数