2011-12-08 59 views
1

代码如下:使用C++ RTTI模板功能,ACC编译器给编译错误

#include<iostream> 
#include<string> 
#include<occi.h> 
using namespace std; using namespace oracle::occi; 

template<class T> void print(T val) { 
    if (typeid(val).name()==typeid((int)1).name()) 
    { 
     val+=2; 
    } 
    else if (typeid(val).name()==typeid((string())).name()) 
    { 
     val+="string"; 
    } 
    cout<<val<<endl; } 

int main() { 
    int a=100; 
    string str="abcdef"; 
    print(str);  
    print(a); 
    return 0; 
} 

ACC编译如下错误信息:

aCC -AA +DD64 -mt -g -D_DEBUG_ -I/oracle/app1/oracle/product/9.2/rdbms/demo -I/oracle/app1/oracle/product/9.2/rdbms/public -I/oracle/app1/oracle/product/9.2/plsql/public -I/oracle/app1/oracle/product/9.2/network/public -c test4.cpp 
Error 203: "test4.cpp", line 16 # Cannot assign 'int' with 'const char *'. 

      val+="string"; 
      ^^^^^^^^ 

Error 445: "test4.cpp", line 21 # Cannot recover from earlier errors. 
    int main() 
    ^^^^^^^^^^ 
*** Error exit code 2 

Stop. 
+1

因为你的函数希望你得到一个编译错误'val'是一个'int'和'string'在同一时间。模板专业化可以轻松解决这个问题,但这不是你问题的主题。 – Marlon

+1

您应该比较'type_info'对象本身,而不是'name()'的结果 - 但不能保证'name()'对于描述相同类型的不同对象返回相同的结果。 (当然,你不应该在这里使用RTTI,因为类型在编译时是已知的)。 –

回答

2

您应该使用模板特化来实现这一:

/* template declaration - no definition (you can add a definition as default 
    for unknown types if you want) 
*/ 
template<class T> void print(T val); 

// This will be used if the parameter is of type int 
template<> 
void print<int>(int val) { 
    val += 2; 
    cout << val << endl; 
} 

// This will be used if the parameter is of type string 
template<> 
void print<std::string>(std::string val) {\ 
    val += "string"; 
    cout << val << endl; 
} 

或者,你可以只写重载要处理每种类型:

// This will be used if the parameter is of type int 
void print(int val) { 
    val += 2; 
    cout << val << endl; 
} 

// This will be used if the parameter is of type string 
void print(std::string val) {\ 
    val += "string"; 
    cout << val << endl; 
} 

模板方法提供了一个优点,即您可以定义一个默认实现,该实现可处理您尚未手动编写实现的所有类型。如果您不需要,超载方法更简单,更安全。

+0

此代码不需要有模板正常工作;简单的重载可以正常工作。 – Dave

+1

不需要使用函数模板,两个重载会更好。 –

+1

模板功能专精[是邪恶](http://www.gotw.ca/publications/mill17.htm)。 – gwiazdorrr

0

针对您尝试传入的每种类型执行打印。由于typeid检查,此代码违反了KISS原则。

1

一个解决方案将封装您的函数的部分依赖于它自己的函数中的数据类型。通过这种方式,您将能够提供你需要一种特定的方式来处理每种类型的重载:

template <typename T> 
void print(T val) 
{ 
    doPrint(val); 
    std::cout << val << std::endl; 
} 

// default case 
template <typename T> 
void doPrint(T & val) 
{} 

// int case 
void doPrint(int & val) 
{ 
    val += 2; 
} 

// string case 
void doPrint(std::string & val) 
{ 
    val += "string"; 
} 

int main() 
{ 
    print(42);     // outputs 44 
    print(std::string("foo")); // outputs foostring 
    print(12.);    // outputs 12 
    print("bar");    // outputs bar 
}