作者回复: 你希望的写法我觉得是写不出来的,而且意义似乎也不大?下面这样写似乎表达能力是一样的,并且可以过:
template <bool Condition, int num1, int num2>
using If = typename If_<Condition>::
template type<num1, num2>;
template <int num1, int num2>
using True = If<true, num1, num2>;
template <int num1, int num2>
using False = If<false, num1, num2>;
作者回复: 那要花时间整理了……后半部分的代码我比较全点,前半部分一开始没有保留所有的测试代码……
作者回复: 嗯,是的,你的写法能少展开一次。👍
作者回复: 没区别。
要点是你不需要使用这些模板,也同样能达到编译期编程的效果。
作者回复: 很好!第 18 讲你会学得很轻松。😉
作者回复: 1. 因为模板的定义就是这个样子,虽然我们平时第二个参数用的都是默认模板参数。
2. 不是右值引用,是转发引用。复习一下第 3 讲结尾部分吧。
作者回复: 我真是自作自受,得看这样的代码。😜
1. 我给的这些模板只是说明能力的,肯定不是让你真的这么写代码的。比如你这种累加,可以考虑这样写(只考虑了正向):
template <int from, int to, int sum, bool ending>
struct sum_two_op;
template <int from, int to, int sum>
struct sum_two_op<from, to, sum, false> {
static const int value = sum;
};
template <int from, int to, int sum>
struct sum_two_op<from, to, sum, true> {
static const int value =
sum_two_op<from + 1, to, sum + from, (from < to)>::value;
};
template <int from, int to>
struct sum_two {
static const int value = sum_two_op<from, to, 0, (from <= to)>::value;
};
2. 你已经很靠近了,只犯了一个小错误,SumTwo 里的方向。应该是:
template <int from, int to>
struct SumTwo {
typedef SumAnyTwo<(from < to), from, to> type;
};
另外,你目前的处理对于 from==to 的情况有点问题。可参考我上面的写法,那是可以正确处理的。
作者回复: 对你的业务场景不熟悉,随便评论几句。
・C++11 里有现成的 mutex、condition_variable 和 unique_lock。
・Client::Lock 和 Client::Unlock 似乎没有用处。
・变量 pending 的命名让人困惑:收到数据了,“挂起”标志被设为真,然后发送数据就能继续往下执行了?连续两次 sendData 中间必须有一次 recvData 才行,而且 sendData 里的等待是在发送之后?这块感觉有问题。
・inter_mutex 和 inter_protect 本身目前没有看出问题。
作者回复: 觉得有趣就好,这个我们要讲上好几讲的。
作者回复: 下面的函数和模板是基本等价的:
int foo(int n)
{
if (n == 2 || n == 3 || n == 5) {
return 1;
} else {
return 2;
}
}
template <int n>
struct Foo {
typedef typename If<
(n == 2 || n == 3 || n == 5),
integral_constant<int, 1>,
integral_constant<int, 2>>::type
type;
};
你可以输出 foo(3),也可以输出 Foo<3>::type::value。
作者回复: 对,对于模板,就是要在脑子里或纸上、电脑上把它展开……☺️
作者回复: 试试 c++1y、c++14 等标准选项了。这个 GCC 太老了……我要求 C++17、GCC 7 的。
作者回复: 拿纸笔来展开试试?实际上就是一种展开而已。
作者回复: 1 是有点编译器魔法的。如果你有析构函数,或者你没有析构函数但有个非 POD 数据成员,is_trivially_destructible 就不成立了。
2 trivial 是很常见的数学术语,没什么特别的。见:
https://baike.baidu.com/item/%E5%B9%B3%E5%87%A1/16739977
https://zh.wikipedia.org/wiki/%E5%B9%B3%E5%87%A1_(%E6%95%B8%E5%AD%B8)
https://en.wikipedia.org/wiki/Triviality_(mathematics)
作者回复: 编译期要连续讲到第 18 讲,甚至之后还会有提到的机会。你喜欢那是最好了。我是怕很多人会被编译期编程吓退呢。😅
policy 这个概念不单独讲,但我觉得在讨论了使用常数来对模板进行特化之后,这个概念应该没有特别之处。我们的例子倒是会有标准库提供的 policy。😁