我的部分模板专业化的模板参数是不可推导的
The template parameter of my partial template specialization is not deducible
请考虑以下代码片段:
template<class E>
class vector_expression {};
template<class Tuple>
class vector
: public vector_expression<vector<Tuple>>
{
public:
using value_type = typename Tuple::value_type;
};
template<typename T>
using dynamic_vector = vector<std::vector<T>>;
namespace detail
{
template<class E>
constexpr bool is_vector_expression_v = std::is_base_of_v<vector_expression<std::decay_t<E>>, std::decay_t<E>>;
template<class E>
struct value_type { using type = std::decay_t<E>; };
template<class E>
struct value_type<vector_expression<std::decay_t<E>>> { using type = typename std::decay_t<E>::value_type; };
template<class E>
using value_type_t = typename value_type<E>::type;
}
int main()
{
static_assert(std::is_same<detail::value_type_t<dynamic_vector<double>>, double>::value, "not the same");
return 0;
}
每当E
是vector_expression
时,我希望value_type_t<E>
是在E
中指定的value_type
。上面的代码不起作用,因为模板参数E
在value_type
的部分专用化中是不可推导的。如何使代码正常工作?
演示
std::decay_t<E>
是不可推导的,因为它实际上是std::decay<E>::type
(事实上,在您的特定情况下,几个E
可以导致相同的类型)。
第二个修复程序需要通过static_assert
:
由于dynamic_vector<double>
不是vector_expression
,而是从中继承的,所以您的专业化不匹配。你可以使用SFINAE来解决这个问题:
template<class E, typename Enabler = void>
struct value_type { using type = std::decay_t<E>; };
template<class E>
struct value_type<E, std::enable_if_t<is_vector_expression_v<E>>> {
using type = typename std::decay_t<typename E::type>::value_type;
};
演示
第一个问题是你的部分专业化是不可推导的。这是一个更容易的解决方案,你只需放下std::decay_t
:
template<class E>
struct value_type<vector_expression<E>> { using type = typename E::value_type; };
然而,现在你有一个更大的问题,那就是它不能做你想做的事情。dynamic_vector<double>
不是任何E
的vector_expression<E>
。它从vector_expression<vector<std::vector<T>>>
继承了,但这对本次匹配没有帮助。因此,上面的修复程序将进行编译,但您仍然会匹配主模板,从而得到错误的value_type
。
您可能想要的是专门研究value_type
作为typedef的存在。即:
template <class... > using void_t = void;
template <class T> struct tag_t { using type = T; }; // courtesy of Yakk
template<class E, class=void>
struct value_type : tag_t<std::decay_t<E>> { };
template<class E>
struct value_type<E, void_t<typename std::decay_t<E>::value_type>>
: tag_t<typename std::decay_t<E>::value_type> { };
现在你的static_assert
通过了。
相关文章:
- 我的神经网络不起作用 [XOR 问题]
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 我的字符计数代码计算错误.为什么
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- cmake在我的项目中所需的所有静态库都不成功
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 为什么我的for循环不能正确获取argv
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 0-1背包代码中的错误.我的代码中有什么错误
- 当我的阵列太大时出现分段错误
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 模板专业化可以进入我的.cpp吗?
- 我应该声明我的函数模板专业化还是定义它们就足够了
- 为什么VS2017拒绝我的功能模板专业化,而不是VS2015拒绝
- 我的部分模板专业化的模板参数是不可推导的
- 模板专业化不能满足我的需要
- 为什么我的模板专业化不起作用
- 无法从我的 Add 函数之外的链表头部获取数据
- 为什么模板专业化中的显式实例化会给我带来错误