The first sample code
GodBolt full link && short link https://godbolt.org/z/zcsW65f7P
bugreport: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165
#include <variant>
#include <unordered_map>
class C{
struct Inner {
int a = 0;
};
struct Outer {
Inner memx;
};
std::unordered_map<int, std::variant<Outer>> table;
};
int main() {}
原因详见bugreport内StackOverflow链接,似乎也是因为dependency cycle。。
https://stackoverflow.com/a/53423881/12529885
The second sample code
Godbolt full link && short link https://godbolt.org/z/5dr4hMb8a
bugreport: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90415
#include <type_traits>
#include <any>
// #include <tuple>
class Adapter {
public:
Adapter(std::any cfg) {}
};
int main() {
bool b = std::is_copy_constructible<Adapter>::value;
// bool c = std::is_copy_constructible<std::tuple<std::any>>::value;
return 0;
}
The gcc and clang with difference versions show different result, someone passed but someone failed.
I use rhel 8.4 with the gcc-8.4.1 and clang 11.0.0 from official rhel repo.
以第二个的编译器报错举例(节选)
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/type_traits:132:31: error: no member named 'value' in 'std::is_copy_constructible<Adapter>'
: public conditional<_B1::value, _B2, _B1>::type
^^^^^^
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/any:170:17: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<Adapter>, std::is_constructible<Adapter, const Adapter &>>' requested here
enable_if<__and_<is_copy_constructible<_Tp>,
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/any:183:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const Adapter &, _Tp = Adapter, _Mgr = std::any::_Manager_internal<Adapter>]
any(_ValueType&& __value)
^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/type_traits:873:56: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const Adapter &, _Tp = (no value), _Mgr = (no value), $3 = (no value), $4 = (no value)]
: public __bool_constant<__is_constructible(_Tp, _Args...)>
^
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/type_traits:897:14: note: in instantiation of template class 'std::__is_copy_constructible_impl<Adapter, true>' requested here
: public __is_copy_constructible_impl<_Tp>
../study/test_gnudeduce.cpp:19:19: note: in instantiation of template class 'std::is_copy_constructible<Adapter>' requested here
bool a = std::is_copy_constructible<Adapter>::value;
节选了一段 进去里看看发现问题如下
__is_constructible
is compiler intrinsic function : https://clang.llvm.org/docs/LanguageExtensions.html#id18is_copy_constructible
的原理是检查T(const T&)是否可以构建- 于是正中下怀,触发了
Adapter(std::any = const Adapter&)
- 可巧不巧std::any要求single values of any copy constructible type : https://en.cppreference.com/w/cpp/utility/any
- 于是在std::any构造函数展开模板时 又检查了
is_copy_constructible
回到第一条 - --- 上面绕圈圈了 ---
- --- 其实我也不确定是否是绕圈圈引起的问题 ---
修了吗?
修了 但又没完全修,有的用clang + llvm-libcxx可以绕开,有的用clang + stdlibc++可以但gcc + stdlibc++不行。。
怎么办呢?一些解决办法如下
class C {
Adapter();
Adapter(std::any, int);
Adapter(int, std::any);
};
class C {
template<typename ...Args>
Adapter(Args&& ...cfg) { init(std::forward<Args>(cfg)...); }
void init(std::any) {}
};
闲话太多 希望以后言简意赅