Garima Singh
Garima Singh

Reputation: 1490

C++ code involving vector works fine on visual studio and not on linux

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

Upvotes: 1

Views: 361

Answers (4)

Adam Burry
Adam Burry

Reputation: 1902

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

Upvotes: 2

BoBTFish
BoBTFish

Reputation: 19767

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

Upvotes: 3

rodrigo
rodrigo

Reputation: 98486

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.

Upvotes: 2

Daniel Frey
Daniel Frey

Reputation: 56903

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).

Upvotes: 7

Related Questions