Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upC++ の面白いコード、トリッキーなコードの話 #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 とか |
実用性はなくてもいいので、面白いネタ的なコードや不思議な文法、仕様のハックなどがあれば教えてください。ある程度たまったら記事にします。
(例) コメントアウトのトリック