模板的用法,看看是什么问题

wh_xiexing 2008-04-07 04:31:08
template <class T>
// min of a,b; nan if either a or b are nan
inline T min(T a, T b)
{
return (a < b) ? a : b;
}

template <>
inline rsip_float32 min<rsip_float32>(rsip_float32 a, rsip_float32 b)
{
if (rsip::isnan(a)||rsip::isnan(b))
{
return rsip::nan();
}
else
{
return (a < b) ? a : b;
}
}

template <>
inline rsip_float64 min<rsip_float64>(rsip_float64 a, rsip_float64 b)
{
if (rsip::isnan(a)||rsip::isnan(b))
{
return rsip::nan();
}
else
{
return (a < b) ? a : b;
}
}


错误提示

e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2027: use of undefined type 'T'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2226: syntax error : unexpected type 'T'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2146: syntax error : missing ')' before identifier 'b'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2146: syntax error : missing ';' before identifier 'b'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2059: syntax error : ')'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2059: syntax error : ')'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(197) : error C2912: explicit specialization; 'rsip_float32 rsip::min<rsip_float32>(rsip_float32,rsip_float32)' is not a specialization of a function template
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(197) : fatal error C1903: unable to recover from previous error(s); stopping compilation
...全文
212 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
icosagon 2008-04-07
  • 打赏
  • 举报
回复
是不是用了using namespace rsip ;
jieao111 2008-04-07
  • 打赏
  • 举报
回复
max , min 是库里定义好的。。不能再重名
lzy340623339 2008-04-07
  • 打赏
  • 举报
回复
你的这个#include <rsipConstants.h>头文件也贴出来吧
wh_xiexing 2008-04-07
  • 打赏
  • 举报
回复
谢谢大家关心, 解决了。 把函数名 max , min 改为 mymax, mymin 就好了。
但只是不明白,这明明是在另外一个空间义的, 怎么会有冲突呢。??
DonyUnx 2008-04-07
  • 打赏
  • 举报
回复
这不按照格式贴,看起来可真要命了,替你顶一下好了,期待高手出现
wh_xiexing 2008-04-07
  • 打赏
  • 举报
回复
太长了, 我分三次贴的。 错误就在第一段的最后的三个函数
wh_xiexing 2008-04-07
  • 打赏
  • 举报
回复
// identical to copysign() but usable in templates
template <class T>
inline T sgn(T x)
// signum function, returns 0, 1, -1, or nan
{
const T table[] = {T(0), T(1), T(-1)};
return table[((x < T(0)) << 1) | (x > T(0))];
}
template <>
inline rsip_float32 sgn<rsip_float32>(rsip_float32 x)
// signum function, returns 0, 1, -1, or nan
{
const rsip_float32 table[] = {rsip_float32(0), rsip_float32(1), rsip_float32(-1)};
return rsip::isnan(x) ? x : table[((x < rsip_float32(0)) << 1) | (x > rsip_float32(0))];
}
template <>
inline rsip_float64 sgn(rsip_float64 x)
// signum function, returns 0, 1, -1, or nan
{
const rsip_float64 table[] = {rsip_float64(0), rsip_float64(1), rsip_float64(-1)};
return rsip::isnan(x) ? x : table[((x < rsip_float64(0)) << 1) | (x > rsip_float64(0))];
}

template <class R, class F>
inline R round(F x)
// correctly round a float, and cast to desired type R
{
R result = static_cast<R>((x < F(0)) ? std::ceil(x - F(0.5)) : std::floor(x + F(0.5)));

rsipENSURE(rsip::isnan(x) == rsip::isnan(result)); // if x is nan, R must be a float type
return result;

// XXX is this better than use of ceil/floor?: return static_cast<long long>((x < T(0)) ? x - T(0.5) : x + T(0.5));
}

inline double ft2mtrs(double feet) { return (feet * MTRS_PER_FT); }
inline double usft2mtrs(double feet) { return (feet * US_METERS_PER_FT); }
inline double mtrs2ft(double meters) { return (meters / MTRS_PER_FT); }
inline double mtrs2usft(double meters) { return (meters / US_METERS_PER_FT); }
// Common conversion functions

template <class T>
std::pair<T, T> quadraticRoots(T a, T b, T c)
// evaluates quadradic formula (positive sqrt is first)
{
// XXX could suffer from catastrophic cancellation,
// see David Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic"
T s = std::sqrt(b*b - T(4)*a*c);
T twoA = T(2)*a;
return std::pair<T, T>((-b + s)/twoA, (-b - s)/twoA);
}

template <class T>
inline void memClear(T& var, int z = 0)
// zero out a variable's memory (for a given value of zero)
{ memset(&var, z, sizeof(T)); }

template <class T>
inline void memClear(T* var)
// prevent user from accidentally passing in a pointer to his struct
{ rsipSTATIC_CHECK(false, YOU_PROBABLY_WANT_TO_MEMCLEAR_WHAT_THE_POINTER_POINTS_TO_NOT_THE_POINTER_ITSELF); }

RSIP_DLL rsipByteOrder byteOrder();
// test endianness of current machine

RSIP_DLL double defaultMin(rsipScalarType scalarType);
RSIP_DLL double defaultMax(rsipScalarType scalarType);
RSIP_DLL double defaultNull(rsipScalarType scalarType);
RSIP_DLL rsip_uint32 scalarSizeInBytes(rsipScalarType scalarType);
// values for various scalar types

RSIP_DLL void defaultTileSize(rsipIpt& tileSize);

RSIP_DLL std::string convertHtmlSpecialCharactersToNormalCharacter(const std::string& src);

/** Heading pitch roll extraction from a matrix. */
RSIP_DLL bool matrixToHpr( rsip_float64 hpr[3],
const NEWMAT::Matrix& rotation );

/** Heading pitch roll extraction from a matrix. */
RSIP_DLL bool matrixToHpr( rsip_float64 hpr[3],
const NEWMAT::Matrix& lsrMatrix,
const NEWMAT::Matrix& rotationalMatrix);

RSIP_DLL void lexQuotedTokens(const std::string& str,
rsip_uint32 start,
const char* whitespace,
const char* quotes,
std::vector<std::string>& tokens, bool& unbalancedQuotes);
// lex str into tokens starting at position start using whitespace
// chars as delimiters and quotes[0] and quotes[1] as the opening
// and closing quotation chars (for quoting tokens containing whitespace).
// unbalancedQuotes is true iff it aborted when detecting unbalanced quoting.
// REQUIRE(whitespace != NULL);
// REQUIRE(quotes != NULL);
// REQUIRE(tokens != NULL);
// REQUIRE(unbalancedQuotes != NULL);

}

#endif /* #ifndef COMMON_H */
wh_xiexing 2008-04-07
  • 打赏
  • 举报
回复
template <class T>
inline T max(T a, T b)
// max of a,b; nan if either a or b are nan
{
return (a < b) ? b : a;
}
template <>
inline rsip_float32 max<rsip_float32>(rsip_float32 a, rsip_float32 b)
{
if (rsip::isnan(b))
return b;
else
return (a < b) ? b : a;
}
template <>
inline rsip_float64 max<rsip_float64>(rsip_float64 a, rsip_float64 b)
{
if (rsip::isnan(b))
return b;
else
return (a < b) ? b : a;
}
inline double radiansToDegrees(double x) { return x*DEG_PER_RAD;}
inline double degreesToRadians(double x) { return x*RAD_PER_DEG;}
inline double cosd(double x) { return cos(x*RAD_PER_DEG); } /*std:: is commented by xiex*/
inline double sind(double x) { return sin(x*RAD_PER_DEG); }
inline double tand(double x) { return tan(x*RAD_PER_DEG); }
// trig fncs with parameter in degrees

inline double acosd(double x) { return DEG_PER_RAD*acos(x); }
inline double asind(double x) { return DEG_PER_RAD*asin(x); }
inline double atand(double x) { return DEG_PER_RAD*atan(x); }
inline double atan2d(double y, double x) { return DEG_PER_RAD*atan2(y,x); }
// trig fncs with result in degrees

template <class IntType>
IntType gcd(IntType n, IntType m)
// greatest common divisor of two ints
// NB: We use n and m as temporaries in this function, so there is no value
// in using const IntType& as we would only need to make a copy anyway...
{
IntType zero(0); // Avoid repeated construction

// This is abs() - given the existence of broken compilers with Koenig
// lookup issues and other problems, I code this explicitly. (Remember,
// IntType may be a user-defined type).
if (n < zero)
n = -n;
if (m < zero)
m = -m;

// As n and m are now positive, we can be sure that %= returns a
// positive value (the standard guarantees this for built-in types,
// and we require it of user-defined types).
for (;;) {
if (m == zero)
return n;
n %= m;
if (n == zero)
return m;
m %= n;
}
}

template <>
inline int gcd<int>(int n, int m)
// greatest common divisor specialize for int.
// XXX this is the old gcd, the above code is the old rsipGcd().
// i made this a specialization of the template above,
// is this really necessary or more efficient, or can we safely delete this specialization?
// i don't know why this fnc must be decled inline, otherwise there's a compile error.
// the simple test case doesn't have this problem.
{
if (m == 0)
return n;
else
return gcd(m, n % m); // gcc can optimize tail calls right?
}

template <class IntType>
IntType lcm(IntType n, IntType m)
// least common multiple
// NB: We use n and m as temporaries in this function, so there is no value
// in using const IntType& as we would only need to make a copy anyway...
{
IntType zero(0); // Avoid repeated construction

if (n == zero || m == zero) {
return zero;
} else {
n /= gcd(n, m);
n *= m;
if (n < zero)
n = -n;
return n;
}
}

template<class T>
inline T square(T x)
{ return x*x; }

wh_xiexing 2008-04-07
  • 打赏
  • 举报
回复
//*******************************************************************
//
// LICENSE: See top level LICENSE.txt file.
//
// Author: Garrett Potts, with some additions and modifciations by
// Patrick Melody
//
// Description: Common file for utility functions.
//
//*************************************************************************
// $Id: rsipCommon.h 12130 2007-12-06 18:11:37Z dburken $
#ifndef COMMON_H
#define COMMON_H


// XXX nullify these for now, but eventually replace with a #include
#define rsipREQUIRE(expr)
#define rsipENSURE(expr)
#define rsipCHECK(expr)
#define rsipSTATIC_CHECK(expr,msg)


#include <cmath>
#include <string>
#include <vector>
#include <rsipConstants.h>
class rsipIpt;
namespace NEWMAT
{
class Matrix;
}

namespace rsip
{
template<class T>
/* inline bool almostEqual(T x, T y, T tolerence = std::numeric_limits<T>::epsilon()) */
/* // are x and y within tolerance distance of each other? */
/* { return std::abs(x - y) <= tolerence; } */
inline bool almostEqual(T x, T y, T tolerence = FLT_EPSILON)
// are x and y within tolerance distance of each other?
{ return std::fabs(x - y) <= tolerence; }

template <class T>
inline bool inInterval(T x, T a, T b)
// is x in the closed interval [a,b]?
{ return x >= a && x <= b; }

template <class T>
inline bool inOpenInterval(T x, T a, T b)
// is x in the open interval (a,b)?
{ return x > a && x < b; }

/**
* isnan Test for floating point Not A Number (NAN) value.
* This should be used test for nan.
* DO NOT USE operator==. Like "if (height == rsip::nan())"
*
* @return true if nan, false if not.
*
* @see nan()
*/
#if defined(WIN32) || defined(_MSC_VER) && !defined(__CYGWIN__) && !defined(__MWERKS__)
inline bool isnan(const float& v) { return _isnan(v); }
inline bool isnan(const double& v) { return _isnan(v); }
#elif defined(sun) || defined(__sun)
# if defined(__SVR4) || defined(__svr4__)
/* Solaris */
inline bool isnan(const float& v) { return ( ::isnan(v) ); }
inline bool isnan(const double& v) { return ( ::isnan(v) ); }
# else
/* SunOS */
inline bool isnan(const float& v) { return ( ::isnan(v) ); }
inline bool isnan(const double& v) { return ( ::isnan(v) ); }
# endif
#else
inline bool isnan(const float& v) { return ( std::isnan(v) ); }
inline bool isnan(const double& v) { return ( std::isnan(v) ); }
#endif

/* #if defined(WIN32) || defined(_MSC_VER) && !defined(__CYGWIN__) && !defined(__MWERKS__) */
/* inline bool isnan(const float& v) { return _isnan(v); } */
/* inline bool isnan(const double& v) { return _isnan(v); } */
/* #else */
/* inline bool isnan(const float& v) { return ( std::isnan(v) ); } */
/* inline bool isnan(const double& v) { return ( std::isnan(v) ); } */
/* #endif */

/** @brief Class lets us see bit patterns of floats. */
class RSIP_DLL IntFloatBitCoercion
{
public:
union
{
rsip_int64 intname;
rsip_float64 floatname;
} bits;
IntFloatBitCoercion(rsip_int64 x) { bits.intname = x; }
IntFloatBitCoercion(rsip_float64 x) { bits.floatname = x; }
};

/**
* @brief Declaration of nan part of nan() declared here for inline
* rsip::nan().
*/
extern RSIP_DLL_DATA(const IntFloatBitCoercion) nanValue;

/**
* @brief Method to return ieee floating point double precision NAN.
*
* @return ieee floating point double precision NAN.
*
* @see isnan()
*
* @note casts seamlessly to float and long double.
*
* @note Use rsip::isnan(v) to test for nan.
* Like "if (isnan(myDoubleValue)) { doSomething; }"
* DO NOT USE operator==. Like "if (myDoubleValue == rsip::nan())"
*/
inline double nan() { return nanValue.bits.floatname; }

template <class S, class T>
inline T lerp(S x, T begin, T end)
// linear interpolation from begin to end by x
{ return x*(end - begin) + begin; }

template <class T>
inline T inverseLerp(T x, T begin, T end)
// inverse of lerp: if lerp(z,begin,end) = x, then inverseLerp(x,begin,end) = z.
// when begin=end, inverseLerp is underconstrained, so we define it to be 0.
{ return begin == end ? (rsip::isnan(x) ? x : T(0)) : (x - begin)/(end - begin); }

template <class S, class T>
T quaderp(S x, T begin, T middle, T end)
// quadratic interpolation through begin,middle,end by x
{
// newton interpolation
const T a1 = S(2)*(middle - begin);
const T a2 = S(2)*(end - middle) - a1;
return x*((x - S(0.5))*a2 + a1) + begin;
}

template <class T>
inline T clamp(T x, T a, T b)
// clamp x to [a, b]
{
rsipREQUIRE(a <= b); // input must make sense, disallow nans

if (rsip::isnan(x)) return x;
if (x < a) return a;
if (b < x) return b;
return x;
}

template <class T>
T wrap(T x, T a, T b)
// wrap x modularly into [a,b)
{
rsipREQUIRE(a <= b); // input must make sense, disallow nans

if (a == b && !rsip::isnan(x))
return a;
else {
T z = x < a ? b : a;
return std::fmod(x - z, b - a) + z;
}
}

// XXX to Garrett from PJM:
// min and max routines. std::min/max do not in fact correctly handle nan.
// this is troublesome, i think my code always was asserting no nans before values got
// through std::min/std::max. i agree with you that if any of the input is nan,
// then the result should be nan, but the STL doesn't really consider the possibility
// that inputs to min/max have a "strange" ordering to them. we could overload
// std::min/max to do this behavior but that's evil. for all my whining, i think
// we should have rsip::max/max that do the right thing wrt nan. however:
// if we "correctly" handle nans like this, does that subtly break any existing code?

template <class T>
// min of a,b; nan if either a or b are nan
inline T min(T a, T b)
{
return (a < b) ? a : b;
}

template <>
inline rsip_float32 min<rsip_float32>(rsip_float32 a, rsip_float32 b)
{
if (rsip::isnan(a)||rsip::isnan(b))
{
return rsip::nan();
}
else
{
return (a < b) ? a : b;
}
}

template <>
inline rsip_float64 min<rsip_float64>(rsip_float64 a, rsip_float64 b)
{
if (rsip::isnan(a)||rsip::isnan(b))
{
return rsip::nan();
}
else
{
return (a < b) ? a : b;
}
}

babyvox1999 2008-04-07
  • 打赏
  • 举报
回复
错误在e:\RSIP_prj\RSIP\base\h\rsipcommon.h这个文件里贴这里的代码
wh_xiexing 2008-04-07
  • 打赏
  • 举报
回复
我用的VS2008
jieao111 2008-04-07
  • 打赏
  • 举报
回复
什么编译器,,我的没有e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2027: use of undefined type 'T'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2226: syntax error : unexpected type 'T'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2146: syntax error : missing ')' before identifier 'b'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2146: syntax error : missing ';' before identifier 'b'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2059: syntax error : ')'
e:\RSIP_prj\RSIP\base\h\rsipcommon.h(181) : error C2059: syntax error : ')'
错误
jieao111 2008-04-07
  • 打赏
  • 举报
回复
先占座

64,720

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧