我想提供一个函数的不同实现,具体取决于它是指针,引用还是常规类型。到目前为止,这是我的代码:
template<class T,
class = typename std::enable_if_t<std::is_reference<T>::value>>
void f(T && in)
{}
// This causes redefinition error
template<class T,
class = typename std::enable_if_t<std::is_pointer<T>::value>>
void f(T && in)
{}
template<class T,
class = typename std::enable_if_t<!std::is_reference<T>::value>,
class = typename std::enable_if_t<!std::is_pointer<T>::value>>
void f(T && in)
{}
中间函数导致:
12:13:错误:重新定义了'template void f(T &&)'
7:13:注意:先前声明的'template void f(T &&)' 这里
有趣的是,只有第一个和最后一个函数可以一起编译。
关于如何解决或简化此代码的任何想法。
答案 0 :(得分:10)
通常的方法是提供适当的重载:
#include <iostream>
template <class T> void f(T&&) {
std::cout << "T&&\n";
}
template <class T> void f(T*) {
std::cout << "T*\n";
}
template <class T> void f(T&) {
std::cout << "T&\n";
}
int main() {
int i;
f(std::move(i));
f(&i);
f(i);
}
这将产生以下输出:
[temp]$ clang++ -std=c++11 test.cpp
[temp]$ ./a.out
T&&
T*
T&
[temp]$
答案 1 :(得分:5)
模板默认参数值不是签名的一部分,因此您需要进一步消除歧义,例如-添加一个额外的虚拟模板参数:
template<class T,
class = typename std::enable_if_t<std::is_reference<T>::value>>
void f(T && in)
{}
// This causes redefinition error
template<class T,
class = typename std::enable_if_t<std::is_pointer<T>::value>, class = void>
void f(T && in)
{}