struct is {
template<typename T>
static constexpr bool _vector() {
if constexpr (std::is_fundamental_v<T>) {
return false;
} else {
return std::is_same_v<T, std::vector<typename T::value_type>>;
}
}
template<typename T>
static constexpr bool vector = _vector<T>();
template<typename T>
static constexpr bool vector2 = std::is_fundamental_v<T> || (!std::is_fundamental_v<T> && std::is_same_v<T, std::vector<typename T::value_type>>);
};
int main(int argc, const char * argv[]) {
std::cout << is::vector2<std::vector<std::vector<int>>::value_type::value_type> << std::endl;
return 0;
}
使用 vector 是 ok 的
使用 vector2 编译会报 Type 'int' cannot be used prior to '::' because it has no members
template<typename T>
static inline constexpr bool A() { ... }
template<typename T>
static inline constexpr bool B() { ... }
template<typename T>
bool b1 =
if constexpr (A) {
return true;
} else {
return B;
}
template<typename T>
bool b2 = A || (!A && B)
简化一下之前问题
b1中,A成立时不会执行B
b2中,A成立也会执行B
没有constexepr 条件运算符
1
q2577 2021-11-13 17:50:40 +08:00 1
```
template<class T> struct is_vector { static constexpr bool value = false; }; template<class T> struct is_vector<std::vector<T> > { static constexpr bool value = true; }; ```` |
4
L4Linux 2021-11-13 18:07:10 +08:00 2
vector2 逻辑操作左右两边在编译时都会求值,所以出现了 int::value_type 。
|
5
GeruzoniAnsasu 2021-11-13 22:08:42 +08:00 1
@L4Linux 不能叫「左右两边都求值」吧,我觉得应该叫「模板替换不受表达式本身的逻辑影响」,就,这个表达式本身的逻辑成不成立并不影响用 int 去替换 T ,这个过程也并没有触发 SFINAE ,所以替换失败,编译报错
@sl0000 那么如果用 SFINAE 来容纳替换错误的表达式,就可以工作了: https://gcc.godbolt.org/z/eE5Gar4z3 |
6
edimetia3d 2021-11-13 23:47:50 +08:00
虽然很不想回, 但是既然都看了. 还是回复一下吧.
1. 麻烦问问题前把代码清理一下, 整理一个最简单的 case 出来. 2. @L4Linux 正解 3. 你把 `if constexpr` 换成 `if`也会编译出错, 一样的道理, 至于这个道理你懂不懂, 就看你了. |
7
test0x01 2021-11-14 00:02:32 +08:00 via Android
我发现,十五年没用 c++, 基本上看不懂了
|
8
Caturra 2021-11-14 00:23:56 +08:00
泛型编程中这种伪·短路运算是不管用的,实例化出来编译器看不懂就是不行( int::value_type ),
但是传统上可以用 SFINAE 或者简单点直接上特化来解决问题 相比之下 if-constexpr 可读性也挺好,不用写一堆 struct (我也想多用点 17 的特性唉 |
9
GeruzoniAnsasu 2021-11-14 00:56:40 +08:00
|
10
GeruzoniAnsasu 2021-11-14 01:35:31 +08:00
另外这个 constexpr if 填补了我一个知识空白:
constexpr 也有类似两段名字查找的特性,如果定义在模板中,那么否定分支中的代码会直接丢弃;如果处于模板实例化阶段,则会正常替换分支两侧的所有需要实例化的模板代码 https://stackoverflow.com/questions/50051473/if-constexpr-in-c17-does-not-work-in-a-non-templated-function 我们吸艹真的太牛逼辣🥵 |