最近のはまりポイント

vcで作ってからgccコンパイルするときにはまった。

その1

関数の実引数が一時変数の時は、仮引数のreferenceはconstでないといけない

#include <iostream>
#include <string>

void func(std::string &text)
{
  std::cout << text << std::endl;
}

int main(int argc, char **argv)
{
  func(std::string("hello"));

  return 0;
}

vcは通ってしまうので気付いてなかった。
void func(const std::string &text)
にしたら通る。
gccのエラーメッセージはこんな感じで判りやすい。

invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type ‘std::string’

その2

typenameが要る。
これもvcだと通っちゃう。
gccだと
typename boost::range_iterator::type
にすると通る。

#include <iostream>
#include <boost/range.hpp>

  template<typename Range>
void func(Range &r)
{
  boost::range_iterator<Range>::type it=boost::begin(r), end=boost::end(r);

  for(; it!=end; ++it){
    std::cout << *it;
  }
  std::cout << std::endl;
}

int main(int argc, char **argv)
{
  func("hello");

  return 0;
};
main.cpp: In function ‘void func(Range&)’:
main.cpp:7: error: expected `;' before ‘it’
main.cpp:9: error: ‘it’ was not declared in this scope
main.cpp:9: error: ‘end’ was not declared in this scope
main.cpp: In function ‘void func(Range&) [with Range = const char [6]]’:
main.cpp:17:   instantiated from here
main.cpp:7: error: dependent-name ‘boost::range_iterator<C>::type’ is parsed as a non-type, but instantiation yields a type
main.cpp:7: note: say ‘typename boost::range_iterator<C>::type’ if a type is meant

こんだけエラーが出てくるがよく見ると最後にtypenameつけたらいいんじゃないですかと書いてある。
知っているとすぐわかるようにはなっている。
boost::gilのbmpエクステンションにもこの問題があった。


基本的にvcの方が緩い感じでわりと通してしまう感じ。
gccもエラーメッセージ読めばわりとわかるんだけど、
テンプレートのエラーメッセージの山に埋まるとつらい。