2017-10-10 4 views
1

次のようbegin()/ end()が定義されていても、範囲ベースのforループはポインタで動作しませんか?ループドキュメント<a href="http://en.cppreference.com/w/cpp/language/range-for" rel="nofollow noreferrer">here</a>ため基づく範囲によれば

begin_exprend_exprが定義されている:

  • range_expressionは、配列型の式である場合、begin_expr__rangeend_expr(__range + __bound)であり、__boundは配列内の要素の数です(配列が未知のサイズまたは不完全な型の場合、プログラムは不正です)
  • range_expressionは、beginというメンバを持つクラス型Cの式です。 /またはその後(種類に関係なく、またはそのような部材のアクセシビリティの)end命名部材、begin_expr__range.beginある)とend_expr__range.end()です。
  • そうでない場合、begin_exprargument-dependent lookupを介して発見さbegin(__range)end_exprend(__range)である(非ADLルックアップが行われません)。

私はポインタ型のためbegin()end()を定義する場合は、それが動作するように失敗しました。

#include <iostream> 

using LPCSTR = char const*; 

LPCSTR begin(LPCSTR str) 
{ 
    return str; 
} 

LPCSTR end(LPCSTR str) 
{ 
    return str + strlen(str); 
} 

int main() 
{ 
    LPCSTR text = "Hello, world!\n"; 
    for (auto c : text) 
    { 
     std::cout << c; 
    } 
} 

エラー(秒):私はポインタがADLから除外されていることをすべての参照が表示されていないので、どのような理由があるだろう

source_file.cpp:18:17: error: invalid range expression of type 'const char *'; no viable 'begin' function available 
    for (auto c : text) 
       ^~~~~ 
1 error generated. 

Demo

なぜこれが機能していないのか?

答えて

2

[basic.lookup.argdep]/2、考慮されるべきゼロ以上の関連する名前空間のセットと、ゼロ以上の関連のクラスの セットがあります...

(2.1) - Tが基本型の場合、関連する名前空間とクラスの両方が空です...

(2.4) - これらからTUへのポインタまたはUの配列である場合、それに関連する名前空間とクラスは、Uに関連するものである...

char const*とasscociated名前空間のセット空であるため、ADLが見ることはありません。

+0

Hmm。知っておいてよかった。 – Adrian

+0

それが動機付けされているかどうか、あるいはそれがそれをどう定義したかということだけが分かっていますか? – Adrian

0

問題はこの部分です:

非ADLのルックアップは、この文脈で

beginendを行っていないポインタが上がらないので、むしろADLよりも、非ADL検索によって発見されるだろう't'はグローバル名前空間で定義されています。 "関数呼び出しの各引数型Tについて

関連する問題