我需要为const和非const类型实现两种不同的方法。我已经设法编写了有效的代码,但我不明白为什么其中有些味道还不错,而有些味道不好。
这里是一个简化的示例,我想知道为什么#1有效但#2无效,并且对于#3与#4相同:
#include <iostream>
#include <vector>
template <typename T>
class X {
public:
// #1 - works
template<typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
void foo() {std::cout << "CONST" << std::endl;}
template<typename B = T, typename std::enable_if<std::is_const<B>::value == false, int>::type = 0>
void foo() {std::cout << "NON-CONST" << std::endl;}
// #2 - does not work "no type named 'type' in 'std::__1::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration"
// template<typename std::enable_if<std::is_const<T>::value, int>::type = 0>
// void foo() {std::cout << "CONST" << std::endl;}
// template<typename std::enable_if<std::is_const<T>::value == false, int>::type = 0>
// void foo() {std::cout << "NON-CONST" << std::endl;}
// #3 - works
// template<typename B = T, typename = typename std::enable_if<std::is_const<B>::value>::type>
// void foo() {std::cout << "CONST" << std::endl;}
// template<typename B = T, typename std::enable_if<std::is_const<B>::value == false>::type * = nullptr>
// void foo() {std::cout << "NON-CONST" << std::endl;}
// # 4 - does not work - "class member cannot be redeclared"
// template<typename B = T, typename = typename std::enable_if<std::is_const<B>::value>::type>
// void foo() {std::cout << "CONST" << std::endl;}
// template<typename B = T, typename = typename std::enable_if<std::is_const<B>::value == false>::type>
// void foo() {std::cout << "NON-CONST" << std::endl;}
};
int main() {
X<int> v;
X<const int> vConst;
v.foo();
vConst.foo();
return 0;
}
即使有更好的方法来解决我的问题,我也很想理解为什么在介绍的示例中enable_if如此工作(而不是这样)。
答案 0 :(得分:5)
#2
无法正常工作,因为T
已由班级修复。
所以你真的有
template<typename std::enable_if<true, int>::type = 0> // -> template<int = 0> void foo();
void foo();
template<typename std::enable_if<false, int>::type = 0> // Hard error failure
void foo();
对于#4
,默认模板值/类型不属于签名的一部分,因此一旦删除,您就拥有了
template <typename B, typename> void foo() {std::cout << "CONST" << std::endl;}
template <typename B, typename> void foo() {std::cout << "NON-CONST" << std::endl;}
具有几种定义的相同方法:破坏ODR。
对于#3
,它将是:
template<typename B, typename>
void foo();
template<typename B, typename std::enable_if<std::is_const<B>::value == false>::type *>
void foo();
不同。