为什么g++ 10.1对头文件中的命名lambda有抱怨,而其他文件没有?

问题描述 投票:0回答:1

我有一个头文件,里面有一个命名的lambda,我用它来测量一些函数的执行时间(这个lambda是这个问题的部分结果) 如何编写一个具有可选返回值的Lambda封装函数?). 它驻留在我从几个翻译单元中包含的头文件中。这在g++ 8和g++ 9中工作得很好。现在当我切换到g++ 10.1时,我在链接时得到一个错误。

请检查下面的缩小的例子。

这是Wandbox中的例子。https:/wandbox.orgpermlinkSizb6txrkW5dkJwT.

文件 "Lambda.h":

#pragma once

#include <string>

auto measure = [](bool enabled, const std::string& taskName, auto&& function,
        auto&&... parameters) -> decltype(auto)
{
    return std::forward<decltype(function)>(function)(
            std::forward<decltype(parameters)>(parameters)...);
};

文件 "Test1.cpp":

#include "Lambda.h"

File "Test2. cpp":

#include "Lambda.h"

然后我像这样构建

g++ -c Test1.cpp
g++ -c Test2.cpp
g++ -shared -o Test.dll Test1.o Test2.o

在g++ 9.2之前一切都很好 但在g++ 10.1中我得到了这个错误信息 为什么?

ld.exe: Test2.o:Test2.cpp:(.bss+0x0): multiple definition of `measure'; Test1.o:Test1.cpp:(.bss+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

我怎样才能用g++ 10.1编译我的项目?我使用命名的lambda就像使用模板函数一样,因此我需要把命名的lambda写到头文件中,才能在工程中的任何地方使用它,我不能以某种方式把声明和定义分开,对吗?

我期待着一个答案

c++ lambda include g++ c++14
1个回答
3
投票

当链接时,我得到一个错误。

为什么会这样?

因为你违反了一次定义规则,多次定义变量。

而其他人却没有?

为什么会这样?

¯_(ツ)_¯语言实现不需要诊断违反ODR。

我使用命名的lambda就像使用模板函数一样,因此我需要把我的命名lambda写到头文件中,才能在项目中的任何地方使用它,我不能以某种方式把声明和定义分开,对吗?

是的。

我如何用g++ 10.1编译我的项目?

简单的解决方案。声明变量 inline (C++17特性)。

一样简单,但有一个奇怪的细节,就是每个TU都有自己的实例。声明一个变量 static.

第三种解决方案。lambda什么也没抓到,所以你可以定义一个模板函数来代替。

第四种解决方案:将lambda存储为全局变量,而不是写一个内联函数来返回lambda的实例。不要把lambda存储为全局变量,而是写一个内联函数来返回lambda的实例。

© www.soinside.com 2019 - 2024. All rights reserved.