常量和非常量类型的相同模板专用化
Same template specialization for const & non const type
我有以下代码:
#include <iostream>
class A
{};
class B
{};
template<typename T>
void Do(T data)
{
std::cout << "Do() defaultn";
}
template<>
void Do(A* data)
{
std::cout << "Do(A*)n";
}
template<>
void Do(B* data)
{
std::cout << "Do(B*)n";
}
int main(int argc, char* argv[])
{
A* a = nullptr;
B* b = nullptr;
const A* aConst = nullptr;
const B* bConst = nullptr;
Do(a);
Do(aConst);
Do(b);
Do(bConst);
return 0;
}
输出:
Do(A*)
Do() default
Do(B*)
Do() default
我应该如何重写代码以共享const&非const类型,无需复制粘贴带有const关键字说明符的专业化,从而生成输出:
Do(A*)
Do(A*)
Do(B*)
Do(B*)
您可以重载,而不是专门化。使用
template<typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, A>, bool> = true>
void Do(T* data)
{
std::cout << "Do(A*)n";
}
template<typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, B>, bool> = true>
void Do(T* data)
{
std::cout << "Do(B*)n";
}
传递const A*
/A*
/const B*
/B*
时将调用这些函数,因为它们比通用模板更匹配。它们是更好匹配的原因是T
更受约束。它被认为是更专业的,因此它将在过载解决中与通用模板的平局中获胜。
C++14
我对这个答案投了赞成票,这对SFINAE来说是一个很好的展示。要对其进行扩展,可以使用std::is_convertible
简化SFINAE表达式。这更类似于重载解析的工作方式(添加const限定符(。
template<typename T, std::enable_if_t<std::is_convertible_v<T*, const A*>, int> = 0>
void Do(T* data)
{
std::cout << "Do(A*)n";
}
template<typename T, std::enable_if_t<std::is_convertible_v<T*, const B*>, int> = 0>
void Do(T* data)
{
std::cout << "Do(B*)n";
}
C++17
另外,在带有constexpr if
的C++17中,您可以在所有情况下使用一个函数:
template<typename T>
void Do(T data)
{
if constexpr (std::is_convertible_v<T, const A*>)
std::cout << "Do(A*)n";
else if constexpr (std::is_convertible_v<T, const B*>)
std::cout << "Do(B*)n";
else
std::cout << "Do() defaultn";
}
如果你愿意写一个小存根,你可以使用这个模式:
template<>
void Do(const A* data)
{
std::cout << "Do(A*)n";
}
template<>
void Do(A* data)
{
Do((const A*)data);
}
您不想复制的主代码使用const A*
,因为您希望它也能处理常量数据。非常简单地转发给它。
相关文章:
- .cpp和.h文件中的模板专用化声明
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 具有常量引用参数的函数模板专用化
- 如何为静态常量模板化专用整数值分配存储
- 常量和非常量类型的相同模板专用化
- 常量字符*的模板方法专用化
- 如何将类成员专用于多个模板值(常量)?
- 合并常量和非常量 std::list 的模板专用化
- 专用常量成员函数的成员检测
- 视图和跨步视图以及常量噩梦的函数模板专用化
- 具有常量参考的可变参数模板专用化
- 常量和非常量 gsl::span 参数的函数模板专用化
- 类型上的模板专用化和常量限定符
- C++模板通过指针的函数/常量指针的函数进行的部分专用化没有什么不同
- 为什么专用模板函数不能同时接受类型及其常量版本?
- 常量和非常量模板专用化