I am working on a C++ program about STL with the latest version of Xcode, and I get the error "Unknown type name 'ubResultData'" and "Unknown type name 'ubFirstArgument'". I have tried to rewrite the program with standard unary_function and binary_function, and the errors remained the same. Then, I build the progaram with VS2010 and VS2013, and it built successfully. What's wrong with the program?
The errors are in the last line of class binder2ND.
#include <iostream>
#include <vector>
using namespace std;
template<typename InputIterator, typename Predicator>
inline int countIF(InputIterator First, InputIterator Last, Predicator Pred){
int count = 0;
for (; First != Last; ++First) {
if(Pred(*First))++count;
}
return count;
}
template<typename Arg1, typename Result>
struct UnaryBase{
typedef Arg1 ubFirstArgument;
typedef Result ubResultData;
};
template<typename Arg1, typename Arg2, typename Result>
struct BinaryBase{
typedef Arg1 bbFirstArgument;
typedef Arg2 bbSecondArgument;
typedef Result bbResultData;
};
template<typename T>
struct LESS:public BinaryBase<T, T, bool>{
bool operator()(const T& Left, const T& Right)const{
return (Left < Right);
}
};
template<typename BinOP>
class binder2ND:public UnaryBase<typename BinOP::bbFirstArgument, typename BinOP::bbResultData>{
protected:
BinOP OP;
typename BinOP::bbSecondArgument Arg2;
public:
binder2ND(const BinOP& Oper, const typename BinOP::bbSecondArgument& valRight):OP(Oper),Arg2(valRight){}
ubResultData operator()(const ubFirstArgument &ubArg1)const{return OP(ubArg1,Arg2);}
};
template<typename BinOP, typename rightVal>
binder2ND<BinOP> bind2ND(const BinOP& OP, const rightVal& vRight){
return binder2ND<BinOP>(OP, vRight);
}
int main(){
vector<int> myVec;
for (int i = 0; i < 50; ++i) {
myVec.push_back(rand()%100);
}
int countNUm = countIF(myVec.begin(), myVec.end(), bind2ND(LESS<int>(), 30));
cout << "Numbers=" << countNUm << endl;
return 0;
}
I don't remember the exact phrasing from the standard, but here's the simplified code that demonstrates the same behavior as yours:
template <typename T> struct A {
typedef T X;
};
template <typename T> struct B: public A<T> {
X x(void) { return 5; }
};
And here's the version that compiles without any errors:
template <typename T> struct A {
typedef T X;
};
template <typename T> struct B: public A<T> {
typename A<T>::X x(void) { return 5; }
};
So basically, you need to specify exactly where this type comes from.
It looks like VS* compilers are a bit more permissive than gcc or clang. :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.