1

I am coding for MRI scanner and the basic requirement is that any sequence code should work on visual studio as well as linux.

I have a part of code which works fine on visual studio 2008; however, gives me error on linux.

Could someone please tell me what am I doing wrong?

template<typename type1, typename type2, typename type3>
void PrintVector3(type1 VectorIn_1, type2 VectorIn_2, type3 VectorIn_3) {   

    type1::const_iterator  i1 = VectorIn_1.begin(); 
    type2::const_iterator  i2 = VectorIn_2.begin();  
    type3::const_iterator  i3 = VectorIn_3.begin(); 
    int lLenghtVec = VectorIn_1.n_elem();

    for(int i = 0; i != lLenghtVec; ++i){
        std::cout << std::setfill('0') << std::setw(3) << *i1 << "      " << *i2 << "      "  << *i3 <<std::endl;
        ++i3; ++i2; ++i1;
    }
}

Errors that I am getting:

CESTiPAT/ReorderInfo_DK.h:185: error: expected ';' before 'i1'
CESTiPAT/ReorderInfo_DK.h:186: error: expected ';' before 'i2'
CESTiPAT/ReorderInfo_DK.h:187: error: expected ';' before 'i3'
CESTiPAT/ReorderInfo_DK.h:191: error: 'i1' was not declared in this scope
CESTiPAT/ReorderInfo_DK.h:191: error: 'i2' was not declared in this scope
CESTiPAT/ReorderInfo_DK.h:191: error: 'i3' was not declared in this scope
Garima Singh
  • 1,102
  • 4
  • 15
  • 40
  • check out [dependent names](http://en.cppreference.com/w/cpp/language/dependent_name) – Dmitry Ledentsov Oct 08 '13 at 15:51
  • Msvc is broken and will be for a while. Best to use another compiler if you aim for portable code. At least these days Msvc 2013 release candidate compiles most standard code you throw at it. But it silently accepts code like this. - which it should not have. – sehe Oct 08 '13 at 15:54
  • First of all, if your vectors are `std::vector`s, then you might want to use `size` instead of `n_elem`, and the type `size_t` instead of int. Then put `typename` before all your iterator declarations. – Dmitry Ledentsov Oct 08 '13 at 15:55
  • as others are suggesting, always compile with something more strict than your VC++ just to be sure. Consider 64bit build as well, since that will find even more errors. And do not ignore warnings – Dmitry Ledentsov Oct 08 '13 at 15:57
  • Incidentally, when you say "compiling on Linux", you should say which compiler, although it didn't really matter in this case. – BoBTFish Oct 08 '13 at 15:59

4 Answers4

7

You need typename:

typename type1::const_iterator  i1 = VectorIn_1.begin(); 
typename type2::const_iterator  i2 = VectorIn_2.begin();  
typename type3::const_iterator  i3 = VectorIn_3.begin(); 

The difference is not because of the platform, but because of the compiler. The typename is required, but your compiler on Windows accepted the broken code anyways. Here's more information on where to put typename (and template).

Community
  • 1
  • 1
Daniel Frey
  • 52,317
  • 11
  • 110
  • 168
3

type1::const_iterator is a dependent name. You need typename type1::const_iterator. Visual Studio is wrong here.

Community
  • 1
  • 1
BoBTFish
  • 17,936
  • 3
  • 49
  • 73
2

You should write:

typename type1::const_iterator i1 = VectorIn_1.begin();
typename type2::const_iterator i2 = VectorIn_2.begin();
typename type3::const_iterator i3 = VectorIn_3.begin();

Because the const_iterator name depends on the template parameter. VSC++ is known for not implementing this part of the language correctly.

rodrigo
  • 79,651
  • 7
  • 121
  • 162
2

As others have pointed out, you need typename.

#include <vector>
#include <iostream>
#include <iomanip>


template<typename type1, typename type2, typename type3>
void PrintVector3(type1 VectorIn_1, type2 VectorIn_2, type3 VectorIn_3) {

    typename type1::const_iterator  i1 = VectorIn_1.begin();
    typename type2::const_iterator  i2 = VectorIn_2.begin();
    typename type3::const_iterator  i3 = VectorIn_3.begin();
    int lLenghtVec = VectorIn_1.size();

    for(int i = 0; i != lLenghtVec; ++i){
        std::cout << std::setfill('0') << std::setw(3) << *i1 << "      " << *i2 << "      "  << *i3 <<std::endl;
        ++i3; ++i2; ++i1;
    }
}

int main() {
  std::vector<int> v(3, 1);

  PrintVector3(v, v, v);
}

But which compiler are you using on Linux? GCC 4.7.3 gave the very clear message:

$ g++ -Wall -Wextra vect.cpp
vect.cpp: In function ‘void PrintVector3(type1, type2, type3)’:
vect.cpp:9:5: error: need ‘typename’ before ‘type1:: const_iterator’ because ‘type1’ is a dependent scope
vect.cpp:9:28: error: expected ‘;’ before ‘i1’
vect.cpp:10:5: error: need ‘typename’ before ‘type2:: const_iterator’ because ‘type2’ is a dependent scope
vect.cpp:10:28: error: expected ‘;’ before ‘i2’
vect.cpp:11:5: error: need ‘typename’ before ‘type3:: const_iterator’ because ‘type3’ is a dependent scope
vect.cpp:11:28: error: expected ‘;’ before ‘i3’
vect.cpp:15:60: error: ‘i1’ was not declared in this scope
vect.cpp:15:79: error: ‘i2’ was not declared in this scope
vect.cpp:15:99: error: ‘i3’ was not declared in this scope
vect.cpp: In instantiation of ‘void PrintVector3(type1, type2, type3) [with type1 = std::vector<int>; type2 = std::vector<int>; type3 = std::vector<int>]’:
vect.cpp:23:23:   required from here
vect.cpp:9:5: error: dependent-name ‘type1:: const_iterator’ is parsed as a non-type, but instantiation yields a type
vect.cpp:9:5: note: say ‘typename type1:: const_iterator’ if a type is meant
vect.cpp:10:5: error: dependent-name ‘type2:: const_iterator’ is parsed as a non-type, but instantiation yields a type
vect.cpp:10:5: note: say ‘typename type2:: const_iterator’ if a type is meant
vect.cpp:11:5: error: dependent-name ‘type3:: const_iterator’ is parsed as a non-type, but instantiation yields a type
vect.cpp:11:5: note: say ‘typename type3:: const_iterator’ if a type is meant
vect.cpp:7:6: warning: unused parameter ‘VectorIn_2’ [-Wunused-parameter]
vect.cpp:7:6: warning: unused parameter ‘VectorIn_3’ [-Wunused-parameter]

The answer to your question is on line 2 of the output!

clang 3.1 similarly says:

$ clang  -c vect.cpp
vect.cpp:9:5: error: missing 'typename' prior to dependent type name
      'type1::const_iterator'
    type1::const_iterator  i1 = VectorIn_1.begin();
    ^~~~~~~~~~~~~~~~~~~~~
    typename
Adam Burry
  • 1,786
  • 11
  • 20