为什么以下不编译?
#include <cstring>
#include <typeindex>
#include <type_traits>
#include <iterator>
#include <vector>
#include <iostream>
template<typename T>
using element_type_t = std::remove_reference_t<decltype(*std::begin(std::declval<T&>()))>;
template<typename T>
struct is_json_allowed : std::integral_constant<bool,
std::is_integral_v<T> || std::is_void_v<T>
|| ( std::is_array_v<T> && is_json_allowed<element_type_t<T>>::value )
|| std::is_same_v<T,std::string> || std::is_floating_point_v<T>
> {};
template<typename T>
inline constexpr bool is_json_allowed_v = is_json_allowed<T>::value;
class Node
{
public:
Node()
:
m_type(typeid(void))
{
}
template<typename T>
std::enable_if_t<is_json_allowed_v<T>,Node&> operator=(const T& rhs)
{
m_type = typeid(T);
m_data.resize(sizeof(T));
std::memcpy(&m_data[0],&rhs,sizeof(T));
}
template<typename T>
Node& operator=(const Node& rhs)
{
m_type = rhs.m_type;
m_data = rhs.m_data;
}
private:
std::type_index m_type;
std::vector<int8_t> m_data;
};
int main()
{
std::cout << is_json_allowed_v<unsigned int> << std::endl;
Node x = 34u;
return 0;
}
编译器(Mingw-Builds 7.3.0)抱怨从unsigned int
转换为非标量类型Node
。我不明白,赋值运算符应该使用34u
的值。
它还抱怨begin
中的成员__cont
请求,这是非类型const unsigned int
。我认为这意味着即使element_type_t
类型显然不是数组,unsigned int
仍在继续。
答案 0 :(得分:0)
为了不依赖模板推导中的短路,您可以使用SFINAE和这样的帮助结构。
#include <cstring>
#include <typeindex>
#include <type_traits>
#include <iterator>
#include <vector>
#include <iostream>
struct not_json_allowed {};
template<typename T>
using element_type_t = std::remove_reference_t<decltype(*std::begin(std::declval<T&>()))>;
template <typename T, typename U = void>
struct element_type {
using type = not_json_allowed;
};
template <typename T>
struct element_type<T, std::enable_if_t<std::is_array_v<T>>> {
using type = element_type_t<T>;
};
template<typename T>
struct is_json_allowed : std::integral_constant<bool,
std::is_integral_v<T> || std::is_void_v<T>
|| std::is_same_v<T,std::string> || std::is_floating_point_v<T>
> {};
template<typename T>
inline constexpr bool is_json_allowed_v = is_json_allowed<T>::value || is_json_allowed<typename element_type<T>::type>::value;
class Node
{
public:
Node()
:
m_type(typeid(void))
{
}
template<typename T>
std::enable_if_t<is_json_allowed_v<T>,Node&> operator=(const T& rhs)
{
m_type = typeid(T);
m_data.resize(sizeof(T));
std::memcpy(&m_data[0],&rhs,sizeof(T));
return *this;
}
template<typename T>
Node& operator=(const Node& rhs)
{
m_type = rhs.m_type;
m_data = rhs.m_data;
return *this;
}
private:
std::type_index m_type;
std::vector<int8_t> m_data;
};
int main()
{
std::cout << is_json_allowed_v<unsigned int> << std::endl;
Node x;
x = 34u;
return 0;
}
我还将main更改为使用了一个assignement,另一个选项是在Node
中添加一个等效的模板构造函数。