std::is_assignable 和 const 指针对象
std::is_assignable and const pointer object
我在尝试使用 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),因为指向 const 的指针不能分配给非常量指针。
它不会匹配 (3),因为它适用于常量类型,而不是指向常量类型的指针。
记住,如果 T
是像 Test*
这样的指针类型,那么 const T
是一个常量指针 Test * const
,而不是指向常量的指针 Test const *
.
tconst
的类型是指向 const Test
的非 const
指针。因此,它匹配 class 模板专业化 no (2)
:
template<typename T>
struct deducer<T, // [...]
与 T = const Test*
,而不是 (3)
,后者匹配 T const
类型(如 Test* const
,不同于 const Test*
)。
但是,它仍然无法编译,退回到您不完整的主 class 模板,因为在尝试分配 const Test*
时可分配性测试不成功(推导 T
) 指向 Object*&
类型的指针(缺少 const
限定符)。
我在尝试使用 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),因为指向 const 的指针不能分配给非常量指针。
它不会匹配 (3),因为它适用于常量类型,而不是指向常量类型的指针。
记住,如果 T
是像 Test*
这样的指针类型,那么 const T
是一个常量指针 Test * const
,而不是指向常量的指针 Test const *
.
tconst
的类型是指向 const Test
的非 const
指针。因此,它匹配 class 模板专业化 no (2)
:
template<typename T>
struct deducer<T, // [...]
与 T = const Test*
,而不是 (3)
,后者匹配 T const
类型(如 Test* const
,不同于 const Test*
)。
但是,它仍然无法编译,退回到您不完整的主 class 模板,因为在尝试分配 const Test*
时可分配性测试不成功(推导 T
) 指向 Object*&
类型的指针(缺少 const
限定符)。