我正在更新一个项目以使用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);
}
Run Code Online (Sandbox Code Playgroud)
在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;
Run Code Online (Sandbox Code Playgroud)
但是,它可以在C ++ 14模式下干净地编译。我发现如果将花括号初始化更改vis{}为括号vis(),则可以在两种模式下正确编译。我尝试过的每个gcc版本都允许在C ++ 17模式下使用这两种变体。
这是从C ++ 14到C ++ 17的正确行为更改,还是这是一个叮当响的错误?如果正确,为什么现在在C ++ 17中无效(或者也许一直如此,但是clang仅在较早的标准版本中允许使用)?