我正在更新一个项目,让它使用C++17,并发现一些遵循这种模式的代码在最近版本的clang上会导致编译错误:
#include <boost/variant.hpp>
struct vis : public boost::static_visitor<void>
{
void operator()(int) const { }
};
int main()
{
boost::variant<int> v = 0;
boost::apply_visitor(vis{}, v);
}
在 C++17 模式下使用 clang v8.0,会导致以下错误:
<source>:11:30: error: temporary of type 'boost::static_visitor<void>' has protected destructor
boost::apply_visitor(vis{}, v);
^
/opt/compiler-explorer/libs/boost_1_64_0/boost/variant/static_visitor.hpp:53:5: note: declared protected here
~static_visitor() = default;
然而,在C++14模式下可以编译。我发现如果我将大括号初始化
vis{}
更改为小括号vis()
,则两种模式都可以正确编译。我尝试的每个gcc版本都允许在C++17模式下使用这两种变体。这是从C++14到C++17行为上的正确变化,还是clang的一个错误?如果是正确的,为什么在C++17中现在无效(或者可能一直无效,但clang只允许在早期标准修订版中使用)?