-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++ の面白いコード、トリッキーなコードの話 #9
Comments
よくある、ヘッダファイル以外をインクルードするとかは、データをコンパイル時に埋め込める便利な記法です。 int ar[] = {
#include "a.csv"
}; ヘッダファイル内で.cpp (相当のファイル) をインクルードするオプションを用意して、ヘッダオンリー化できるようにしているのとかは、ライブラリを作るにあたって設計選択のひとつになっています。 https://github.com/boostorg/chrono/blob/develop/include/boost/chrono/thread_clock.hpp (最近はシングルヘッダ版を自動生成するとかもありますが) |
プリプロセス関係だと、文字列リテラルの結合とかも、マイナーですがたまに便利ですね。自前のprintfやassertを作るときにも使いますし、長い文字列リテラルを分割して書くのにも便利です。 #include <cstdio>
#define INFO(fmt, ...) std::printf("[info] " fmt "\n" __VA_OPT__(,) __VA_ARGS__)
#define DEBUG(fmt, ...) std::printf("[debug] " fmt "\n" __VA_OPT__(,) __VA_ARGS__)
int main()
{
INFO("hello");
DEBUG("hello %d", 123);
} #include <iostream>
int main()
{
std::string help = "The application is designed by ME.\n"
"Welcome my application";
std::cout << help << std::endl;
} |
csvのインクルードとかを多用するようになると、以前私がブログに書いた以下のようなものがほしくなります。 |
コメントありがとうございます! 引き続き募集してます。
#include <iostream>
int main()
{
int i = 10;
while (i --> 0)
{
std::cout << i << '\n';
}
} |
template関数のオーバーロードに優先順位を付けるやつ: #include<cstdint>
template<std::size_t N>struct priority : priority<N-1>{};
template<> struct priority<0>{};
#include<iostream>
#include<type_traits>
template<
typename T,
std::enable_if_t<std::is_same<std::decay_t<T>, float>::value, std::nullptr_t> = nullptr
>
void f_impl(T t, priority<1>){std::cout << "float " << t << std::endl;}
template<typename T>
void f_impl(T t, priority<0>){std::cout << "T " << t << std::endl;}
template<typename T>
void f(T&& t){f_impl(std::forward<T>(t), priority<1>{});}
int main(){
f(3.1);
f(3.14f);
f("3.141592");
} |
面白いかは分からないですが、リテラル0だけを受け取る関数(nullptrからは目を逸らして・・・) struct minus {
constexpr bool operator<(std::nullptr_t) {
return true;
}
constexpr bool operator>(std::nullptr_t) {
return false;
}
};
void f(std::nullptr_t) {
std::cout << "literal 0" << std::endl;
} |
コンパイルできそうだけどできないコードたち
|
#include <type_traits>
template <typename T>
void f(T)
{
if constexpr (std::is_same_v<T, int>)
{
// Tがintのときのみ評価される
static_assert([]{return false;}());
}
}
int main()
{
f(2.4);
f(3);
} https://cpprefjp.github.io/lang/cpp17/if_constexpr.html |
input streamの中身をまるごとoutput streamにぶちこむやつ os << is.rdbuf(); |
Most vexing parse: https://en.wikipedia.org/wiki/Most_vexing_parse |
暗黙の型変換にやられるやつ(ただのバグ)
|
名前空間の付け忘れにやられるやつ(ただのバグ)
|
template <int>
int a = 0;
int main() {
//a<10>= 1; // 動かない
a<10> = 1;
} スペースの有無で演算子と解釈されるかどうか異なります |
(特別C++に限らないけけど) Fast inverse square root とか |
https://wandbox.org/permlink/fXQKYqQAgMiyMMf9
|
constexprが普通に使えるこんにちは出番がなさそう・・・? |
@zxc-key 提案ありがとうございます。
【面白いネタ的なコードや不思議な文法】として cppmap で新規に取り上げるネタはありませんでしたが、また面白いコードを見つけたら教えてください 🖐 |
int main()
{
[]{};
[]{}();
[](){};
[](){}();
[[]][]{};
[]()[[]]{};
[[]][]{}();
[[]][](){};
[]()[[]]{}();
[[]][](){}();
[[]][]()[[]]{};
[[]][]()[[]]{}();
} ネタの一つとして提供:https://twitter.com/yohhoy/status/1367790416007897089 |
#include <iostream>
using T = int&;
void f(T&) { std::cout << "non-const" << std::endl; }
void f(const T&) { std::cout << "const" << std::endl; }
int main() {
int x;
f(x);
}
コンパイルできそうでできないやつです。 |
#include <type_traits>
using T = int&;
using T2 = const T&;
static_assert(std::is_same_v<T, T2>); |
長い演算子 (演算子の優先順位的にできるやつ) #include <iostream>
int main() {
int a = 10, b = 10;
a = a +-+-+-+-+-+-+-+-+ 6 +-+-+-+-+-+-+-+-+ 5;
b = b + + + + + + + + + 6 - - - - - - - - - 5;
std::cout << a << '\n';
std::cout << b << '\n';
return 0;
} |
実用性はなくてもいいので、面白いネタ的なコードや不思議な文法、仕様のハックなどがあれば教えてください。ある程度たまったら記事にします。
(例) コメントアウトのトリック
The text was updated successfully, but these errors were encountered: