2010-11-28 13 views
3

私はUbuntuのCodeBlocks IDEでg ++を使用しています。 私はSTLとC++の新機能です。STLの学習中のいくつかの問題

Q1://は

std::istream_iterator<std::string> begin (dictionaryFile); 
std::istream_iterator<std::string> end; 
std::vector< std::string> dictionary; 
std::copy (begin, end, std::back_inserter (dictionary)); 

に答えは正しいですが、私は

std::istream_iterator<std::string> end(); 

std::istream_iterator<std::string> end; 

を変更したときに、コンパイラは、第四行で一致する関数呼び出しを述べていません。

Q2://申し訳ありませんが私はfirstLess1とfirstLess2間の唯一の違いはfirstLess1はPSで宣言されていることであるという問題が最初に

struct PS : std::pair< std::string, std::string > { 
PS(); 
static struct FirstLess: std::binary_function< PS, PS, bool> { 
    bool operator() (const PS & p, const PS & q) const { 
     return p.first < q.first; 
    } 
} firstLess1; }; 


struct FirstLess: std::binary_function< PS, PS, bool> { 
bool operator() (const PS & p, const PS & q) const { 
    return p.first < q.first; 
}} firstLess2; 

注意をクリアすることはありませんでした。

私は関数を呼び出す:

k = std::find_if (j + 1, finis, std::not1 (std::bind1st (PS::firstLess1, *j))); 

コンパイラは私にエラー 'PS :: firstLess1に未定義の参照' を与えました。 と変更してから

k = std::find_if (j + 1, finis, std::not1 (std::bind1st (firstLess2, *j))); 

に変更しました。

もっと奇妙な、プログラムの他の部分では、私は両方の

j = std::adjacent_find (j , finis, PS::firstLess1); 
j = std::adjacent_find (j , finis, firstLess2); 

を使用し、コンパイラは私にエラーを与えていませんでした。

+0

OK。私は2番目の質問を解決する方法を考え出しました(しかし、まだわからない) k = std :: find_if(j + 1、finis、std :: not1(std :: bind1st(PS :: FirstLess()、* j))); OK か、const PS :: FirstEqual PS :: firstEqual1 = PS :: FirstEqual()を追加できます。宣言の後に。 – user522829

答えて

4

std::istream_iterator<std::string> end();これは、戻り値の型がendで、引数のリストが空の関数の宣言と解釈されます。それはなぜあなたがそのようなエラーを取得する。 C++では、そのクラスのデフォルトのコンストラクタを呼び出すことによってオブジェクトを作成するには、これを行う必要がありますtype_name variable_name;type_name variable_name();は関数宣言として解釈されます。

+1

これは私たちが[最も厄介な構文解析](http://en.wikipedia.org/wiki/Most_vexing_parse)と呼ぶものです。 –

1

A1:

イニシャライザ括弧の空集合である、すなわちオブジェクトは、()、の値に初期化しなければなりません。

[注:()初期化するための構文によって許可されていないので

X();

は、クラスXのオブジェクトの宣言ではなく、関数の宣言は、引数を取らないとX.

フォームを返す()5.2、5.3.4(特定の他の初期化コンテキストで許可されています3、12.6.2)。 - エンドノート]

A2:

私はあなたが欲しいものを本当にわからないんだけど、STD :: find_ifとstd :: adjacent_find comepletely異なる何かをします。しかし、とにかく、ここであなたのことに触発されたいくつかの作業コードがあります。

#include <iostream> 
#include <algorithm> 
#include <string> 
#include <vector> 

typedef std::pair<std::string, std::string> TwoStrings; 

struct FirstLess : std::binary_function<TwoStrings, TwoStrings, bool> 
{ 
    bool operator() (const TwoStrings& p, const TwoStrings& q) const { 
     return p.first < q.first; 
    } 
}; 

int main() 
{ 
    std::vector<TwoStrings> v; 
    std::vector<TwoStrings>::iterator it; 
    v.push_back(TwoStrings("4. Here's ", "Johnny")); 
    v.push_back(TwoStrings("1. Here's ", "Johnny")); 
    v.push_back(TwoStrings("2. Here's ", "Johnny")); 
    v.push_back(TwoStrings("2. Here's ", "Johnny")); 
    v.push_back(TwoStrings("3. Here's ", "Johnny")); 

    it = std::adjacent_find(v.begin(), v.end(), FirstLess()); 
    std::cout << it->first << it->second << std::endl; 

    it = std::find_if(v.begin() , v.end(), std::not1(std::bind1st(FirstLess(), *(v.begin())))); 
    std::cout << it->first << it->second << std::endl; 
} 

A出力は次のとおりです。

1. Here's Johnny 
4. Here's Johnny 
2

A1:すでに十分
A2に答え:(参照firstLessの宣言にconstとして追加し、ORのcppファイルにfirstLessオブジェクトを定義this

+0

+1は* firstLessオブジェクト*を定義します。つまり、囲みスコープ内に定義します(リンク先ページの最上部の行を参照してください)。この場合、 'const'を追加することは構造体ではなく整数型の静的メンバーに対してのみ機能します。 (驚くべきことは、コンパイラが 'adjacent_find()'呼び出しを許可していることです)。 –

+0

@j_random_hacker:それを修正しました。しかし、それは本当に積分型のために動くべきですか?過去にPOD構造体で私のために働いていた... – smerlin

+0

私は知らない:)私はそれが動作することが期待されるべきではないと言うことができます。しかしコンパイラは標準に反しないものを自由に許可していますが、私はそうは思わないのです。 –