std::is_assignable 和常量指针对象

std::is_assignable and const pointer object

本文关键字:常量 指针 对象 assignable is std      更新时间:2023-10-16

我在尝试用std::is_assignable推断事物时遇到了一个小问题

我的代码:

#include <string>
#include <type_traits>
class Object{};
enum my_conv {
  string, const_object, object
};
template<typename T, typename V = void>
struct deducer;
template<typename T>
struct deducer<T, typename std::enable_if< std::is_constructible<std::string, T>::value >::type > {
  static const my_conv value = my_conv::string;
}; // (1) test for string                                                                                              
template<typename T>
struct deducer<T, typename std::enable_if< std::is_assignable<Object*&, T>::value >::type > {
  static const my_conv value = my_conv::object;
}; // (2) test for Object derived                                                                                      
template<typename T>
struct deducer<const T, typename std::enable_if< std::is_assignable<Object*&, T>::value >::type > {
  static const my_conv value = my_conv::const_object;
}; // (3) should test for const Object derived                                                                         
class Test : public Object {
public:
  Test() = default;
};
int main() {
  std::string   str;
  Test*         t = new Test;
  const Test*   tconst = static_cast<const Test*>(t);
  deducer<decltype(t)>::value;// deduce as (1)                                                                         
  deducer<decltype(str)>::value;//deduce as (2)                                                                        
  deducer<decltype(tconst)>::value;//fail to deduce as (3)... why?                                                     
}

而且我真的不明白为什么编译器无法实例化第三个推导器......

编辑:

在测试时,我看到这样写道:

struct deducer<const T*, typename std::enable_if< std::is_assignable<Object*&, T*>::value >::type >

让它工作,但我想我仍然需要一些解释......因为我还是不明白第一时间出了什么问题......

显然它不会匹配(1),因为const Test *无法从std::string构造。

它不会匹配 (2),因为指向常量的指针不可分配给非常量指针。

它不会匹配 (3),因为这适用于常量类型,而不是指向常量类型的指针。

请记住,如果T是像Test*这样的指针类型,那么const T是一个常量指针Test * const,而不是指向常量Test const *的指针。

tconst的类型是指向const Test的非const指针。因此,它与类模板专用化匹配,没有(2)

template<typename T>
struct deducer<T, // [...]

T = const Test* ,而不是 (3) ,它匹配T const类型(如 Test* const ,它与 const Test* 不同)。

但是,它仍然无法编译,回退到不完整的主类模板,因为当尝试将const Test*(推导T)分配给Object*&类型的指针(缺少const限定符)时,可分配性测试不成功。