[閒聊] C++ Stateful Metaprogramming
之前有人發現 C++11/14/17 標準有個漏洞,
透過 friend + template + noexcept 可以讓一個 constexpr expression 有不同的值
原理大概是這樣的:
==============================================================================
constexpr function 可以是有定義或沒定義,這會影響到 noexcept 和 SFINAE 的結果:
constexpr void f();
constexpr void g() {};
constexpr bool a = noexcept(f()); // false
constexpr bool b = noexcept(g()); // true
如果我們可以控制一個 constexpr function 有無定義,
就可以將他當作一個 bit 來使用,
這點可以用 template + friend function 給定義達成:
constexpr void flag(int); // 宣告 flag
template<typename T>
struct writer {
friend void flag(T) {}
// 當 writer<int> 被 instatinate 時,會定義 void flag(int)
};
constexpr bool a = noexcept(flag(0)); // false
writer<int> w; // instatinate `writer<int>`
constexpr bool b = noexcept(flag(0)); // true
static_assert(a != b);
int main() {
std::cout << a << ' ' << b << std::endl; // 0 1
}
http://coliru.stacked-crooked.com/a/a6cc0faeb9f215c8
有了這鬼東西以後,就可以做出 compile-time 的 counter :
static_assert(next() != next());
http://coliru.stacked-crooked.com/a/648448a3a8d03275
稍微包裝一下就可以做出 constify 的功能:
begin_mutable_region(r); // 宣告 r
auto x = r::make<int>(1);
auto v = r::make<std::vector<int>>();
x.get() = 42; // 修改 x
v.get().emplace_back(42); // 修改 v
end_mutable_region(r); // 之後不可再修改透過 r::make 製造出來的東西
x.get() = 43; // Error
v.get().clear(); // Error
std::cout << x << std::endl; // 還是可以透過 const int& 存取 x
http://coliru.stacked-crooked.com/a/3d63a2e82c173055
其原理就是透過設定 r 當作旗標,若 r 被設立時就關閉 non-const 的 overload
不過這個技巧被 C++ 委員會認為是 ill-formed:
https://wg21.cmeerw.net/cwg/issue2118
所以未來應該會修改標準禁止這鬼東西,至於具體要怎麼做現在似乎還沒有提案
參考:
Non-constant constant expressions in C++:
http://b.atch.se/posts/non-constant-constant-expressions/
How to implement a constant-expression counter in C++
http://b.atch.se/posts/constexpr-counter/
用 stateful metaprogramming 模擬 Rust 的 borrow checker:
https://medium.com/@bhuztez/db4b5e94449f
https://github.com/bhuztez/borrow
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.113.193.217
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1505626198.A.ED9.html
推
09/17 14:23, , 1F
09/17 14:23, 1F
推
09/17 15:15, , 2F
09/17 15:15, 2F
※ 編輯: PkmX (140.113.193.217), 09/17/2017 15:36:12
→
09/17 16:48, , 3F
09/17 16:48, 3F
→
09/17 18:44, , 4F
09/17 18:44, 4F
→
09/17 18:45, , 5F
09/17 18:45, 5F
→
09/17 18:46, , 6F
09/17 18:46, 6F
推
09/17 19:46, , 7F
09/17 19:46, 7F
→
09/17 21:21, , 8F
09/17 21:21, 8F
→
09/17 21:21, , 9F
09/17 21:21, 9F
→
09/17 21:37, , 10F
09/17 21:37, 10F
→
09/17 21:38, , 11F
09/17 21:38, 11F
→
09/17 23:43, , 12F
09/17 23:43, 12F
推
09/17 23:58, , 13F
09/17 23:58, 13F
→
09/18 00:26, , 14F
09/18 00:26, 14F
推
09/18 00:38, , 15F
09/18 00:38, 15F
→
09/18 06:39, , 16F
09/18 06:39, 16F
→
09/18 06:41, , 17F
09/18 06:41, 17F
→
09/18 06:41, , 18F
09/18 06:41, 18F
→
09/18 06:45, , 19F
09/18 06:45, 19F
→
09/18 08:03, , 20F
09/18 08:03, 20F
推
09/18 08:41, , 21F
09/18 08:41, 21F
→
09/18 08:41, , 22F
09/18 08:41, 22F
推
09/18 10:31, , 23F
09/18 10:31, 23F
→
09/18 11:46, , 24F
09/18 11:46, 24F
→
09/18 11:47, , 25F
09/18 11:47, 25F
→
09/18 11:48, , 26F
09/18 11:48, 26F
→
09/18 11:49, , 27F
09/18 11:49, 27F
→
09/18 11:49, , 28F
09/18 11:49, 28F
推
09/18 12:10, , 29F
09/18 12:10, 29F
推
09/18 12:39, , 30F
09/18 12:39, 30F
推
09/18 12:45, , 31F
09/18 12:45, 31F
→
09/18 12:46, , 32F
09/18 12:46, 32F
→
09/18 12:47, , 33F
09/18 12:47, 33F
→
09/18 12:47, , 34F
09/18 12:47, 34F
推
09/18 13:14, , 35F
09/18 13:14, 35F
噓
09/18 13:29, , 36F
09/18 13:29, 36F
→
09/18 13:29, , 37F
09/18 13:29, 37F
→
09/18 13:29, , 38F
09/18 13:29, 38F
還有 56 則推文
→
09/20 09:50, , 95F
09/20 09:50, 95F
→
09/20 09:50, , 96F
09/20 09:50, 96F
推
09/20 10:38, , 97F
09/20 10:38, 97F
推
09/20 10:54, , 98F
09/20 10:54, 98F
→
09/20 10:54, , 99F
09/20 10:54, 99F
→
09/20 10:54, , 100F
09/20 10:54, 100F
→
09/20 10:55, , 101F
09/20 10:55, 101F
推
09/20 11:33, , 102F
09/20 11:33, 102F
→
09/20 12:27, , 103F
09/20 12:27, 103F
推
09/21 06:23, , 104F
09/21 06:23, 104F
推
09/21 09:14, , 105F
09/21 09:14, 105F
推
09/22 07:22, , 106F
09/22 07:22, 106F
→
09/22 07:23, , 107F
09/22 07:23, 107F
→
09/22 07:23, , 108F
09/22 07:23, 108F
→
09/22 07:23, , 109F
09/22 07:23, 109F
→
09/22 07:25, , 110F
09/22 07:25, 110F
→
09/22 07:25, , 111F
09/22 07:25, 111F
噓
09/22 07:35, , 112F
09/22 07:35, 112F
→
09/22 21:10, , 113F
09/22 21:10, 113F
→
09/22 21:11, , 114F
09/22 21:11, 114F
→
09/22 21:12, , 115F
09/22 21:12, 115F
→
09/22 21:14, , 116F
09/22 21:14, 116F
→
09/22 21:17, , 117F
09/22 21:17, 117F
→
09/22 21:18, , 118F
09/22 21:18, 118F
→
09/22 21:20, , 119F
09/22 21:20, 119F
→
09/22 21:21, , 120F
09/22 21:21, 120F
→
09/22 21:21, , 121F
09/22 21:21, 121F
推
09/22 23:09, , 122F
09/22 23:09, 122F
→
09/22 23:09, , 123F
09/22 23:09, 123F
→
09/22 23:09, , 124F
09/22 23:09, 124F
→
09/22 23:09, , 125F
09/22 23:09, 125F
→
09/23 09:33, , 126F
09/23 09:33, 126F
噓
09/23 14:06, , 127F
09/23 14:06, 127F
→
09/23 14:06, , 128F
09/23 14:06, 128F
→
09/23 14:07, , 129F
09/23 14:07, 129F
推
09/23 16:57, , 130F
09/23 16:57, 130F
→
09/23 16:57, , 131F
09/23 16:57, 131F
→
09/24 00:08, , 132F
09/24 00:08, 132F
→
09/24 00:08, , 133F
09/24 00:08, 133F
→
10/07 11:09, , 134F
10/07 11:09, 134F
討論串 (同標題文章)
完整討論串 (本文為第 1 之 3 篇):
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章