2011-12-15 35 views
-1

我有簡單的類,如this(其行爲像Boost :: overload,但具有命名函數(我用它來簡化\縮小反射\內省目的))。它對輸入參數有多個返回類型有問題(編譯器錯誤3066)。我的代碼:重載函數映射容器中的C++函數返回類型:自動扣除失敗,編譯器錯誤

#include <iostream> 
#include <string> 
#include <map> 
#include <vector> 

template < class T0, class T1 > 
class my_map { 
    typedef T0 type_0; 
    typedef T1 type_1; 
    std::map < std::string, type_0 * >T0_var; 
    std::map < std::string, type_1 * >T1_var; 
    friend class apitemp; 
public: 
    my_map(int meaningless0 = 42, int meaningless1 = 42) {} 
    class apitemp { 
     std::string n_; 
     my_map *p; 
    public: 
     apitemp(std::string name_, my_map * parent):n_(name_), p(parent) {} 
     operator type_0 *() { 
      return p->T0_var[n_]; 
     } 
     operator type_1 *() { 
      return p->T1_var[n_]; 
     } 
    }; 
    void insert(std::string name, type_0 * ptr) { 
     T0_var[name] = ptr; 
    } 
    void insert(std::string name, type_1 * ptr) { 
     T1_var[name] = ptr; 
    } 
    apitemp operator[] (std::string n_) { 
     return apitemp(n_, this); 
    } 
}; 

template<class out, class in1, class in2> 
    out hello_world(in1 name, in2 number) 
{ 
    name += "!"; 
    std::cout << "Hello, " << name << std::endl; 
    return number; 
} 

template<class in1, class in2> 
std::string hello_world(in1 name, in2 number) 
{ 
    name += "!"; 
    std::cout << "Hello, " << name << std::endl; 
    return std::string("Yep, we can!"); 
} 

int main() { 
    int a = hello_world<int, std::string, const int &>("Tim", 25); 
    std::string b = hello_world<std::string, const int &>("Tim", 25); 

    my_map<int(std::string, const int &), std::string(std::string, const int &)> myMap; 
    myMap.insert("my_method_hello", &hello_world<int, std::string, const int &>); 
    myMap.insert("my_method_hello2", &hello_world<std::string, const int &>); 
    //int a = myMap["my_method_hello"]("Tim", 25); // error C3066: there are multiple ways that an object of this type can be called with these arguments 
    //std::string b = myMap["my_method_hello2"]("Tim", 25); // // error C3066: there are multiple ways that an object of this type can be called with these arguments 

    std::cin.get(); 
} 

如何向其API引入多重返回類型函數? API用戶方式有可能無法使用嗎?或者至少用一些API用戶干擾如

int a = myMap["my_method_hello"]("Tim", 25)::int; 
std::string b = myMap["my_method_hello2"]("Tim", 25)::string; 

+2

「是否有可能用於API用戶方式?」 - 是谷歌翻譯? – sehe 2011-12-15 08:02:31

回答

3

執行此操作的一種方法是讓myMap["my_method_hello"]("Tim", 25)返回一個代理對象,該對象爲您希望它返回的每種類型定義operator int()operator std::string()等。另一種方法是讓代理對象爲每種類型定義明確的.asInt().asString()方法。

如果目標類型在源代碼中不明確(例如,如果將結果傳遞給函數),則重載運算符技術可能會引起混淆。同樣,代理類型可能會混淆傳遞給它的模板函數,並且如果候選集合包含同時採用intstd::string(或代理自動轉換爲的其他類型)的函數,將無法輕鬆選擇重載函數。因此,我建議提供.asInt()等功能,除此之外沒有任何運營商。

您也可以拼出.asInt()等功能,如template<typename T> as()和使用明確的分工來定義新的轉換。唯一的缺點這是源代碼難以閱讀

相關問題