基于模板类型指针的条件函数行为
Posted
技术标签:
【中文标题】基于模板类型指针的条件函数行为【英文标题】:Conditional function behavior based on pointer-ness of template type 【发布时间】:2018-12-03 09:30:54 【问题描述】:我正在尝试为模板类提出一个成员函数:
在模板类型是指针的情况下做一些事情 对非指针什么都不做不确定 SFINAE 是否适用于此,因为我需要这两个版本,因为我在类本身中调用它们。请注意,我仅限于 C++11。
template < typename T_ = T, typename = std::enable_if_t <!std::is_pointer<T_> > >
void SomeFunction()
// Do nothing
template < typename T_ = T, typename = std::enable_if_t < std::is_pointer<T_> > >
void SomeFunction()
// Do sth
编译器报错 error C2535: member function already defined or declared。
【问题讨论】:
***.com/questions/53351945/… 另一个复杂的 SFINAE 可以用 C++17 变得非常简单if constexpr
。
【参考方案1】:
问题是默认模板参数不是function template signature 的一部分。这两个SomeFunction
s 被认为是相同的,然后导致重新声明错误。
两个函数模板被认为是等价的
它们在同一范围内声明 他们有相同的名字 它们具有相同的模板参数列表 返回类型和参数列表中涉及模板参数的表达式是等价的
您可以在返回类型中使用它们,例如(针对 C++11)
template <typename T_ = T>
typename std::enable_if<!std::is_pointer<T_>::value>::type SomeFunction()
// Do nothing
template <typename T_ = T>
typename std::enable_if<std::is_pointer<T_>::value>::type SomeFunction()
// Do sth
LIVE
或者在非类型模板参数列表中使用它们,例如(针对 C++11)
template < typename T_ = T, typename std::enable_if<!std::is_pointer<T_>::value>::type* = nullptr>
void SomeFunction()
// Do nothing
std::cout << "Do nothing\n";
template < typename T_ = T, typename std::enable_if<std::is_pointer<T_>::value>::type* = nullptr>
void SomeFunction()
// Do sth
std::cout << "Do sth\n";
LIVE
【讨论】:
太棒了!更简洁的版本是template < typename T_ = T, typename std::enable_if_t < !std::is_pointer<T_> >* = nullptr>
【参考方案2】:
问题在于两个函数模板声明是等价的,因此编译器认为您的代码包含 2 个函数定义的唯一函数。
函数模板等效性在[temp.over.link]/6 和[temp.over.link]/7 中进行了描述。
在您的具体情况下,问题在于这个等价性没有考虑到默认模板参数。
如果你添加一个默认的模板参数,这两个功能将不等效:
template < typename T_ = T
, typename = std::enable_if_t <!std::is_pointer<T_> > >
void SomeFunction()
// Do nothing
template < typename T_ = T
, class=void
, typename = std::enable_if_t < std::is_pointer<T_> > >
void SomeFunction()
// Do sth
【讨论】:
以上是关于基于模板类型指针的条件函数行为的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin学习—— 基本语法,函数,变量,字符串模板,条件表达式,null,类型检测,for,while,when,区间,集合
简化条件表达式之以多态取代条件表达式(Replace Conditional with Polymorphism)
Kotlin空安全总结 ( 变量可空性 | 手动空安全管理 | 空安全调用操作符 | 非空断言操作符 | 空合并操作符 | 空指针异常处理 | 先决条件函数判空 )