Skip to content
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

Open
Reputeless opened this issue Mar 12, 2019 · 14 comments
Open

C++ の面白いコード、トリッキーなコードの話 #9

Reputeless opened this issue Mar 12, 2019 · 14 comments
Labels

Comments

@Reputeless
Copy link
Member

@Reputeless Reputeless commented Mar 12, 2019

実用性はなくてもいいので、面白いネタ的なコードや不思議な文法、仕様のハックなどがあれば教えてください。ある程度たまったら記事にします。

  • 数行~十数行で完結するぐらいが好ましいです
  • マイナーなものでも有名なものでも OK です

(例) コメントアウトのトリック

@Reputeless Reputeless added the 募集 label Mar 12, 2019
@faithandbrave
Copy link
Contributor

@faithandbrave faithandbrave commented Mar 12, 2019

よくある、ヘッダファイル以外をインクルードするとかは、データをコンパイル時に埋め込める便利な記法です。

int ar[] = {
    #include "a.csv"
};

ヘッダファイル内で.cpp (相当のファイル) をインクルードするオプションを用意して、ヘッダオンリー化できるようにしているのとかは、ライブラリを作るにあたって設計選択のひとつになっています。

https://github.com/boostorg/chrono/blob/develop/include/boost/chrono/thread_clock.hpp

(最近はシングルヘッダ版を自動生成するとかもありますが)

@faithandbrave
Copy link
Contributor

@faithandbrave faithandbrave commented Mar 12, 2019

プリプロセス関係だと、文字列リテラルの結合とかも、マイナーですがたまに便利ですね。自前の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;
}
@faithandbrave
Copy link
Contributor

@faithandbrave faithandbrave commented Mar 12, 2019

csvのインクルードとかを多用するようになると、以前私がブログに書いた以下のようなものがほしくなります。

@Reputeless
Copy link
Member Author

@Reputeless Reputeless commented Mar 12, 2019

コメントありがとうございます! 引き続き募集してます。

--> 演算子

#include <iostream>

int main()
{
	int i = 10;

	while (i --> 0)
	{
		std::cout << i << '\n';
	}
}
@wx257osn2
Copy link
Contributor

@wx257osn2 wx257osn2 commented Mar 12, 2019

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");
}

Wandbox

@onihusube
Copy link
Contributor

@onihusube onihusube commented Mar 12, 2019

面白いかは分からないですが、リテラル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;
}

https://wandbox.org/permlink/sDe2GzeQuPk1hMT0

@Fuyutsubaki
Copy link
Contributor

@Fuyutsubaki Fuyutsubaki commented Mar 12, 2019

コンパイルできそうだけどできないコードたち

void f2(std::shared_ptr<int>=0);
void f(int*=0);
int a[3];
a[[]{return 0;}()];

https://wandbox.org/permlink/P76EMNyoE6FAQaDs

@yumetodo
Copy link
Contributor

@yumetodo yumetodo commented Mar 13, 2019

false_vを作らないでlambda式でif constexpr内のstatic_assertの評価を遅延させるやつ

#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
cpprefjp/site#577
by @alphya

@yumetodo
Copy link
Contributor

@yumetodo yumetodo commented Mar 13, 2019

input streamの中身をまるごとoutput streamにぶちこむやつ

os << is.rdbuf();
@rhysd
Copy link
Contributor

@rhysd rhysd commented Mar 14, 2019

@agehama
Copy link

@agehama agehama commented Mar 14, 2019

暗黙の型変換にやられるやつ(ただのバグ)

#include <iostream>

int main()
{
    if(-1 < 1u)
    {
        std::cout << "-1 < 1u";
    }
    else
    {
        std::cout << "-1 > 1u";
    }
}
@agehama
Copy link

@agehama agehama commented Mar 14, 2019

名前空間の付け忘れにやられるやつ(ただのバグ)

#include <iostream>
#include <cmath>

int main()
{
    //std::cout << std::abs(0.5); // 0.5
    std::cout << abs(0.5);        // 0
}
@nekko1119
Copy link
Contributor

@nekko1119 nekko1119 commented Mar 16, 2019

template <int>
int a = 0;

int main() {
    //a<10>= 1; // 動かない
    a<10> = 1;
}

スペースの有無で演算子と解釈されるかどうか異なります

@Fuyutsubaki
Copy link
Contributor

@Fuyutsubaki Fuyutsubaki commented Mar 18, 2019

(特別C++に限らないけけど) Fast inverse square root とか

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants
You can’t perform that action at this time.