这是libstdc ++中具有std :: any或std :: is_copy_constructible的错误,还是合法错误?

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

我遇到了一个相当麻烦的情况,在这种情况下,我试图将std :: make_any与我编写的类一起使用,该类在其构造函数之一中接受std :: any,但尝试提出一个最小的测试用例,遇到了我认为可能是std :: any和/或std :: is_copy_constructible的实现中的错误,但是我不确定100%。以下是一些最小的示例,这些示例在使用g ++ 8和clang ++ 9时可能会起作用,也可能不会起作用。在每个示例中,都存在所有相同的代码行,但是处于两种状态的状态下,即是否注释掉了两行,并显示了结果。

[我正在使用C ++ 17标准,将-std=c++17标志同时传递给g ++-8和clang ++-9,它们都使用libstdc ++版本8.3.0(Ubuntu 18.04)。

以下代码同时使用g ++-8和clang ++-9进行编译。

#include <any>
#include <type_traits>

struct Hippo {
    Hippo () { }
    Hippo (Hippo const &) { }
    Hippo (Hippo &&) { }
//     Hippo (std::any) { }
};

int main (int argc, char **argv) {
    static_assert(std::is_copy_constructible_v<Hippo>);
//     auto w = std::make_any<Hippo>();
    return 0;
}

正如预期的那样,以下内容也适用于两者。

#include <any>
#include <type_traits>

struct Hippo {
    Hippo () { }
    Hippo (Hippo const &) { }
    Hippo (Hippo &&) { }
//     Hippo (std::any) { }
};

int main (int argc, char **argv) {
    static_assert(std::is_copy_constructible_v<Hippo>);
    auto w = std::make_any<Hippo>();
    return 0;
}

以下代码使用g ++-8进行编译,但是对于clang ++-9则失败。这令人困惑,因为std::is_copy_constructible_v<Hippo>的值不应通过添加与副本构造无关的构造函数来更改。

#include <any>
#include <type_traits>

struct Hippo {
    Hippo () { }
    Hippo (Hippo const &) { }
    Hippo (Hippo &&) { }
    Hippo (std::any) { }
};

int main (int argc, char **argv) {
    static_assert(std::is_copy_constructible_v<Hippo>);
//     auto w = std::make_any<Hippo>();
    return 0;
}

clang ++-9给出的错误(已排除长度):

/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/type_traits:132:31: error: no member named 'value' in 'std::is_copy_constructible<Hippo>'
    : public conditional<_B1::value, _B2, _B1>::type
                         ~~~~~^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/any:170:17: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<Hippo>, std::is_constructible<Hippo, const Hippo &> >' requested here
      enable_if<__and_<is_copy_constructible<_Tp>,

[这里,std::is_copy_constructible<Hippo>类型在使用时看起来不完整(在<any>标头中),但是应该具有布尔值constexpr value成员。我认为这是一个错误,因为g ++ 8可以很好地进行编译。大概该错误是在libstdc ++的std :: any和/或std :: is_copy_constructible的实现中实现的,但是由于g ++-8可以工作并且clang ++-9失败,因此令人困惑。

但是,以下在g ++-8和clang ++-9中均无法编译:

#include <any>
#include <type_traits>

struct Hippo {
    Hippo () { }
    Hippo (Hippo const &) { }
    Hippo (Hippo &&) { }
    Hippo (std::any) { }
};

int main (int argc, char **argv) {
    static_assert(std::is_copy_constructible_v<Hippo>);
    auto w = std::make_any<Hippo>();
    return 0;
}

不足为奇的是,clang ++-9产生的错误是相同的,但是g ++-8的错误声称,所有模板参数推导的候选都对std :: any的构造函数失败,包括应该起作用的构造函数,但埋在该构造函数中是std :: is_copy_constructible的用法,所以我认为弹出的问题是相同的,我很确定这是一个错误。我已经删掉了错误消息的无关部分:

/usr/include/c++/8/any: In instantiation of ‘std::any std::make_any(_Args&& ...) [with _Tp = Hippo; _Args = {}]’:
.../any.cpp:13:35:   required from here
/usr/include/c++/8/any:431:14: error: no matching function for call to ‘std::any::any(const std::in_place_type_t<Hippo>&)’
       return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<...cut for length...>
/usr/include/c++/8/any:208:7: note: candidate: ‘template<class _ValueType, class ... _Args, class _Tp, class _Mgr, typename std::enable_if<std::__and_<std::is_copy_constructible<_Tp>, std::is_constructible<_Tp, _Args&& ...> >::value, bool>::type <anonymous> > std::any::any(std::in_place_type_t<_Tp>, _Args&& ...)’
       any(in_place_type_t<_ValueType>, _Args&&... __args)
       ^~~
/usr/include/c++/8/any:208:7: note:   template argument deduction/substitution failed:
<...cut for length...>

无论如何,我的问题仍然存在-这是libstdc ++中的错误,对吧?

c++17 typetraits libstdc++ stdany
1个回答
0
投票

在全面研究此问题时,我尝试针对libc ++(仅使用clang ++-9)而不是libstdc ++进行编译,从而解决了该问题。因此,这似乎是libstdc ++ 8.3.0中的合法错误。

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