используйте C ++ RTTI в шаблонной функции, компилятор aCC выдаст ошибку компиляции - PullRequest
1 голос
/ 08 декабря 2011

код следующим образом:

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

Ответы [ 3 ]

2 голосов
/ 08 декабря 2011

Вы должны использовать специализацию шаблона для достижения этой цели:

/* 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;
}

Шаблонный подходпреимущество в том, что вы можете определить реализацию по умолчанию, которая обрабатывает все типы, для которых вы не написали реализацию вручную.Если вам это не требуется, то подход с перегрузкой проще и безопаснее.

1 голос
/ 08 декабря 2011

Решением будет инкапсуляция части вашей функции, которая зависит от типа данных в ее собственной функции.Таким образом, вы сможете обеспечить перегрузки для каждого типа, который вам нужно обработать определенным образом:

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
}
0 голосов
/ 08 декабря 2011

Создайте реализацию print для каждого типа, который вы пытаетесь передать.Этот код нарушает принцип KISS из-за проверки typeid.

...