带有默认std :: function参数的模板化函数会导致符号[...]已定义

jpi*_*ihl 5 c++ templates std-function

我只是碰到了一些奇怪的东西.我想知道这是不是一个错误,如果不是,我希望有人可以解释这个问题.

我的问题是,当我创建一个std::function带有默认参数的模板化函数时,我只能创建一个这个函数的模板实例,否则会出错.

请考虑以下代码:

#include <functional>

template<bool B>
void wut(std::function<void()> f = []() {})
{
    f();
}

int main() {
    wut<false>(); // works
    wut<false>(); // still works
    wut<true>();  // error
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

https://ideone.com/VlVcUv

编译此代码时,我收到以下错误:

{standard input}: Assembler messages:
{standard input}:28: Error: symbol `_ZNSt14_Function_base13_Base_managerIUlvE_E10_M_managerERSt9_Any_dataRKS3_St18_Manager_operation' is already defined
{standard input}:127: Error: symbol `_ZNSt17_Function_handlerIFbvEUlvE_E9_M_invokeERKSt9_Any_data' is already defined
Run Code Online (Sandbox Code Playgroud)

Sha*_*our 2

这是一个 gcc bug(在 7.3 版之后看起来已修复),我们可以通过查看[expr.prim.lambda.capture]p9节来看到这一点节来看到这一点:

\n\n
\n

默认参数中出现的 lambda 表达式不应隐式或显式捕获任何实体。[例子:

\n\n
void f2() {\nint i = 1;\nvoid g1(int = ([i]{ return i; })()); // ill-formed\nvoid g2(int = ([i]{ return 0; })()); // ill-formed\nvoid g3(int = ([=]{ return i; })()); // ill-formed\nvoid g4(int = ([=]{ return 0; })()); // OK\nvoid g5(int = ([]{ return sizeof i; })()); // OK\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94结束示例]

\n
\n\n

作为 IDEOne 的替代方案,您可以使用 Wandbox,它与 gcc 和 clang 版本保持最新,请参阅您的示例

\n