altebute.hatenablog.com

犬も歩けば規格にあたる

cv修飾された仮引数はUniversal Referenceになれない

以下のコードは合法である。

#include <type_traits>
#include <iostream>
#include <boost/type_index.hpp>

using namespace std;
using boost::typeindex::type_id_with_cvr; 

template< typename Arg > void f( Arg&& arg )
{
    cout << "`Arg`   is `" << type_id_with_cvr< Arg >() << "`" << endl;
    cout << "`Arg&&` is `" << type_id_with_cvr< decltype( arg ) >() << "`" << endl;
}

int main()
{
    int a;
    f( a );
    cout << "================" << endl;
    f( move( a ) );
}

出力

Start
`Arg`   is `int&`
`Arg&&` is `int&`
================
`Arg`   is `int`
`Arg&&` is `int&&`
0
Finish

一方で、関数 f の引数にcv修飾を行うとコンパイルエラーとなる。

...
template< typename Arg > void f( Arg const&& arg )
...

出力

Start
prog.cc:18:5: error: no matching function for call to 'f'
    f( a );
    ^
prog.cc:9:31: note: candidate function [with Arg = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument
template< typename Arg > void f( Arg const&& arg )
                              ^
1 error generated.
1
Finish

型推論と実際の型

仮引数の宣言 実引数 Arg の型 arg の型
Arg&& arg a int& int&
Arg&& arg std::move( a ) int int&&
Arg const&& arg a int int const&&
Arg const&& arg std::move( a ) int int const&&

表を見れば明白な様に、Reference Collapsingは直接的原因ではない。 コンパイルエラーの原因は、仮引数の型が int const&& の関数に対し、渡された実引数が lvalue であるためであり、 更にその原因は、テンプレート仮引数の型推論において、仮引数の宣言が Arg const&& arg の時、 Arg の型が int に推論されているためである。

直感的には、 Argint& に推論され、 arg に対して lvalue が束縛されて欲しい所だが、 表を見れば、そもそも仮引数の宣言が Arg&& arg かつ実引数が a の時、 仮引数の宣言が参照であるにも関わらず、 Arg の型が int& に推論されている状況が特殊である事が分かる。

ここで規格先生にご登場願う。 以下は項 14.8.2.1 より引用。

3
If P is a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction. If P is a reference type, the type referred to by P is used for type deduction. If P is an rvalue reference to a cvunqualified template parameter and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction. [ Example:
template <class T> int f(T&&);
template <class T> int g(const T&&);
int i;
int n1 = f(i); // calls f<int&>(int&)
int n2 = f(0); // calls f<int>(int&&)
int n3 = g(i); // error: would call g<int>(const int&&), which
               // would bind an rvalue reference to an lvalue
— end example ]

以下翻訳

3
仮引数がcv修飾された型の場合、最初の仮引数の型へのcv修飾子は型推論の段階で無視される。もし仮引数が参照型の場合、仮引数における参照部分は型推論に使われる。もし仮引数がcv修飾されていない rvalue reference であり、実引数が lvalue の場合、型推論には型「実引数への lvalue reference 」が実引数の代わりに使われる。

つまり、cv修飾されてない Arg&& arg が特別扱いされるのであり、仮引数がcv修飾されている場合、通常の型推論の規則、即ち 「関数テンプレートのテンプレート型引数の推論において、推論される型引数は参照を除去した型になる」という規則が適用される。

参照型に対するcv修飾子はill-formedまたは無視される

const int&const int への参照であるため、well-formedであるが、 int& constint&に対するcv修飾であるためill-formedである。
ただし、cv修飾される型名が typedef-name または decltype-specifier の場合、cv修飾子は無視される。
また、同時に reference collapsing が起きる場合も、cv修飾子は同様に無視される。

このため、明示的にcv修飾を行った場合も、予想しない型になる場合がある。

#include <type_traits>
#include <iostream>
#include <boost/type_index.hpp>

using namespace std;
using boost::typeindex::type_id_with_cvr; 

template< typename Arg > void f()
{
    cout << "================================" << endl;
    cout << "`Arg`         is `" << type_id_with_cvr< Arg         >() << "`." << endl;
    cout << "`Arg&`        is `" << type_id_with_cvr< Arg&        >() << "`." << endl;
    cout << "`Arg&&`       is `" << type_id_with_cvr< Arg&&       >() << "`." << endl;
    cout << "--------------------------------" << endl;
    cout << "`Arg const`   is `" << type_id_with_cvr< Arg const   >() << "`." << endl;
    cout << "`Arg const&`  is `" << type_id_with_cvr< Arg const&  >() << "`." << endl;
    cout << "`Arg const&&` is `" << type_id_with_cvr< Arg const&& >() << "`." << endl;
}

int main()
{
    f< int         >();
    f< int&        >();
    f< int&&       >();
    f< const int   >();
    f< const int&  >();
    f< const int&& >();
    cout << "================================" << endl;
    cout << "voltile work same as const." << endl;
}

出力

> Start
================================
`Arg`         is `int`.
`Arg&`        is `int&`.
`Arg&&`       is `int&&`.
--------------------------------
`Arg const`   is `int const`.
`Arg const&`  is `int const&`.
`Arg const&&` is `int const&&`.
================================
`Arg`         is `int&`.
`Arg&`        is `int&`.
`Arg&&`       is `int&`.
--------------------------------
`Arg const`   is `int&`.
`Arg const&`  is `int&`.
`Arg const&&` is `int&`.
================================
`Arg`         is `int&&`.
`Arg&`        is `int&`.
`Arg&&`       is `int&&`.
--------------------------------
`Arg const`   is `int&&`.
`Arg const&`  is `int&`.
`Arg const&&` is `int&&`.
================================
`Arg`         is `int const`.
`Arg&`        is `int const&`.
`Arg&&`       is `int const&&`.
--------------------------------
`Arg const`   is `int const`.
`Arg const&`  is `int const&`.
`Arg const&&` is `int const&&`.
================================
`Arg`         is `int const&`.
`Arg&`        is `int const&`.
`Arg&&`       is `int const&`.
--------------------------------
`Arg const`   is `int const&`.
`Arg const&`  is `int const&`.
`Arg const&&` is `int const&`.
================================
`Arg`         is `int const&&`.
`Arg&`        is `int const&`.
`Arg&&`       is `int const&&`.
--------------------------------
`Arg const`   is `int const&&`.
`Arg const&`  is `int const&`.
`Arg const&&` is `int const&&`.
================================
voltile work same as const.
0
Finish

以下は N3797 項 8.3.2 より引用。

1
In a declaration T D where D has either of the forms & attribute-specifier-seqoptD1 && attribute-specifier-seqoptD1 and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T,” then the type of the identifier of D is “derived-declarator-type-list reference to T.” The optional attribute-specifier-seq appertains to the reference type. Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name (7.1.3, 14.1) or decltype-specificer (7.1.6.2), in which case the cv-qualifiers are ignored. [ Example: typedef int& A; const A aref = 3; // ill-formed; lvalue reference to non-const initialized with rvalue The type of aref is “lvalue reference to int”, not “lvalue reference to const int”. ? end example ] [ Note: A reference can be thought of as a name of an object. ? end note ] A declarator that specifies the type “reference to cv void” is ill-formed.

6
If a typedef-name (7.1.3, 14.1) or a decltype-specifier (7.1.6.2) denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.

Android 6.0 Marshmallowでアスキーアートを表示する

ブートループになっても知りません。 分からない所は調べてください。

大まかな順序

  1. Androidの開発者向け環境を整え、パスを通す
  2. adb reboot bootloader
  3. twrpを送信しブート( fastboot boot )
  4. twrp上で/systemをマウント
  5. adb pull /system/etc/fonts.xml
  6. fonts.xmlを書き換え
  7. adb push fonts.xml /system/etc
  8. adb push textar.ttf /system/fonts
  9. 書き換えたファイルの属性が644であることを確認
  10. adb reboot

書き換え内容

    ...
    <family name="sans-serif">
        <font weight="100" style="normal">Roboto-Thin.ttf</font>
        ...
        <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
    </family>

    <family name="MS PGothic">
        <font weight="400" style="normal">textar-min.ttf</font>
    </family>

    <alias name="MS Pゴシック" to="MS PGothic" />

    <!-- Note that aliases must come after the fonts they reference. -->
    ...

注意

  • ...は単なる中略
  • 文字コードUTF-8
  • タブではなく半角スペース4つ
  • 改行はLF

adb pushの際に、systemパーティションの容量不足で失敗する場合がある。

ワカラナイ シラナイ コムギコカナニカダ

マルチディスプレイ時に稀に一部のディスプレイが表示されない場合の対処法

普段デュアルディスプレイ環境を使用しているのだが、稀にサブディスプレイが表示されない場合がある。

傾向を察するに、アナログディスプレイとの接続時に、ディスプレイとグラフィックスカードの相性が悪いと、接続を検知出来ないのかもしれない。

多くの場合、再起動したり、スリープから復帰すると戻るのだが、うまくいかないケースもあり面倒だ。

以下の方法で簡単かつ素早く解決出来るケースが多い。

  1. デバイス マネージャーを起動する
  2. ディスプレイ アダプターのツリーを展開
  3. 使用しているデバイスのプロパティを開く
  4. ドライバータブを開く
  5. 無効(D)ボタンを押す
  6. 再度有効にする

PushbulletのPortalが凄いかも知れない。

PCとAndroid端末をWEBを介して接続し、様々なプッシュ通知を行うサービスを提供しているPushbulletが、新しいアプリPortalをリリースした。

Pushbulletでは、Androidに届いた通知を、PC側のブラウザの拡張機能を用いて、GoogleクラウドメッセージングサービスやAppleのプッシュ通知サービスを介して受け取ったり、小さなファイルを転送する事ができた。*1

Portalでは、(恐らくは同様の方法を用いて)ブラウザのみで認証を行い、Android側にファイルを転送する事が出来る。この際、認証によって、同じLAN内にある時のみ接続を確立し、ファイルの転送はLAN内で行われる。

このため、Pushbulletとは異なり、サイズの大きいファイルも転送する事が出来るほか、WEB上にファイルをアップロードし、パブリックなURLを介して転送を行う必要が無く、よりセキュアかつ高速だ。

利用方法も簡単だ。

  1. Android側にアプリケーションをインストールする。
  2. PC側で portal.pushbullet.com を開く。
  3. 表示されたQRコードAndroid側で読みとり、認証、接続を確立する。
  4. ドラッグ&ドロップでファイルを転送する。

フォルダや、複数ファイルを同時に転送するにはPC側でChrome拡張をインストールする必要があるようだ。

Pushbulletはセキュリティに関しても見やすい位置にきちんと表示しているので、心配な人はそこを見るといいだろう。個人的になWEBを介した認証を行うとLAN内での接続が確立される仕組みが気になる所だ。

更に現在ベータテスター募集も行っているようだ。*2

*1:これらの仕組みはSeculityのページに書かれている。

*2:Introducing Portal

RAR for Androidが素晴らしい件

Android上でzipアーカイブを解凍するためにRAR for Androidを導入したのだが、これが素晴らしかった。

Android向けのアーカイブの解凍アプリは多数あるが、RAR for Androidの特筆すべき点はアーカイブ内にパスに日本語を含むファイルも文字化けを起こす事無く解凍出来る点である。

WinZipではディレクトリ構造もファイル名も完全に壊れ、ファイル自体も破損してしまい(単に壊れたパスだったから対応するソフトがファイルアクセスに失敗しただけかも)使い物にならなかった。

次に気に入っている点は、RAR for Androidがファイラの機能を内蔵する事だ。ファイラは多くの権限を要求するため、その扱いには細心の注意を要するが、RARLABは老舗であり、個人的にはESファイルエクスプローラーのES APP Groupや、アストロファイルマネージャーのMetago等よりも信用出来る(あくまでも比較的、という話だが)。

Windows 10 Build 10130でPINによるサインインが出来なくなった時の対処法

  1. 設定 -> アカウント -> サインイン オプション
  2. 暗証番号 (PIN) -> PIN を忘れた場合
  3. 指示に従って再設定

上記の手順でPINによるサインインが利用出来るようになる。