gpt4 book ai didi

c++11 - Clang 3.5和3.6之间的过载分辨率更改是否正确还是错误?

转载 作者:行者123 更新时间:2023-12-03 08:42:45 25 4
gpt4 key购买 nike

下面的代码在Visual Studio 2013,gcc 4.8,clang 3.4和clang 3.5(Apple LLVM 6.0)中编译,但不在clang 3.6中(通过Apple LLVM 6.1)编译

该代码是我们代码库中复杂类的简化版本,这是显示问题的最低要求。

问题的症结在于,由于存在接受TYPED_VALUE的构造函数,因此在3.6中,STRING的副本构造将评估STRING类型的模板化转换运算符;这将导致对std::is_constructible进行求值,从而导致它需要STRING的定义(我们在此无法提供-会导致完整代码中的循环依赖)。

class STRING;

class TYPED_VALUE
{
public:
TYPED_VALUE( const TYPED_VALUE& ) = default; // explicit or implicit doesn't make a difference
TYPED_VALUE( const STRING & ) {}

template< typename TYPE, typename std::enable_if<!std::is_pointer< TYPE >::value && !std::is_constructible< TYPE, const STRING& >::value && !std::is_constructible< TYPE, bool >::value, int >::type = 0 >
operator TYPE( void ) const = delete;
};

class TYPED_STORAGE
{
public:
TYPED_STORAGE( const TYPED_VALUE &v ) : value( v ) {}

TYPED_VALUE value;
};

错误消息是
/type_traits:2329:38: error: incomplete type 'SICORE::STRING' used in type trait expression
: public integral_constant<bool, __is_constructible(_Tp, _Args...)>
^
/main.cpp:348:99: note: in instantiation of template class 'std::__1::is_constructible<SICORE::STRING, const SICORE::STRING &>' requested here
template< typename TYPE, typename std::enable_if<!std::is_pointer< TYPE >::value && !std::is_constructible< TYPE, const STRING& >::value && !std::is_constructible< TYPE, bool >::value, int >::type = 0 >
^
/main.cpp:349:9: note: while substituting prior template arguments into non-type template parameter [with TYPE = SICORE::STRING]
operator TYPE( void ) const = delete;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
/main.cpp:355:56: note: while substituting deduced template arguments into function template 'operator type-parameter-0-0' [with TYPE = SICORE::STRING, $1 = (no value)]
TYPED_STORAGE( const TYPED_VALUE &v ) : value( v ) {}
^
/main.cpp:340:11: note: forward declaration of 'SICORE::STRING'
class STRING;
^

对我来说,这似乎是3.6中的错误,在以前的版本中,重载分辨率确定了复制构造函数最适合而不需要评估模板参数-我试图理解标准中的重载分辨率注释,但我认为这很困惑我更多;)

(可以通过明确实现构造函数或转换运算符来解决此问题,但这不是我们想要的行为)

那里有标准专家知道答案吗?

最佳答案

我相信Clang会产生此错误是正确的:

第10段中C++标准的[temp.inst]部分说:

If a function template or a member function template specialization is used in a way that involves overload resolution, a declaration of the specialization is implicitly instantiated (14.8.3).



形成对TYPE_VALUE构造函数的调用的重载候选进行排名所需的隐式转换序列,需要实例化转换运算符。对特征使用不完整的类型参数不会形成无效的类型,因此这不是替代失败,而是一个硬错误。

关于c++11 - Clang 3.5和3.6之间的过载分辨率更改是否正确还是错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29616985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com