我需要为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;
}
Run Code Online (Sandbox Code Playgroud)
即使有更好的方法来解决我的问题,我也很想理解为什么enable_if的工作原理(不是)在所提供的示例中有效.
#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();
Run Code Online (Sandbox Code Playgroud)
因为#4,默认模板值/类型不是签名的一部分,所以一旦删除,你就有了
template <typename B, typename> void foo() {std::cout << "CONST" << std::endl;}
template <typename B, typename> void foo() {std::cout << "NON-CONST" << std::endl;}
Run Code Online (Sandbox Code Playgroud)
具有多个定义的相同方法:您打破ODR.
因为#3,它将是:
template<typename B, typename>
void foo();
template<typename B, typename std::enable_if<std::is_const<B>::value == false>::type *>
void foo();
Run Code Online (Sandbox Code Playgroud)
这是不同的.
| 归档时间: |
|
| 查看次数: |
364 次 |
| 最近记录: |