2009-08-14 44 views
1

如果我想創建一個函數模板,在模板參數未在參數列表中使用,我正是如此做:操作模板

template<T> 
T myFunction() 
{ 
//return some T 
} 

但調用必須指定「T '使用,因爲編譯器不知道如何解決。

myFunction<int>(); 

但是,假設我想做類似的事情,但對'[]'操作符。 模板

T SomeObject::operator [ unsigned int ] 
{ 
    //Return some T 
} 

有什麼辦法可以調用這個操作符嗎? 不出現有效:

SomeObject a; 
a<int>[3]; 

回答

6

這應該工作:

class C 
{ 
public: 
    template <class T> 
    T operator[](int n) 
    { 
     return T(); 
    } 
}; 

void foo() 
{ 
    C c; 

    int x = c.operator[]<int>(0); 
} 

但它沒有真正的價值,因爲你總是要指定類型,因此它看起來像一個非常醜陋的函數調用 - 一個運算符重載的點看起來像一個操作符調用。

+0

不錯,我不知道你能做到這一點!但是,這樣做會挫敗使用操作符超負荷的好處。 – Scott 2009-08-14 06:58:44

+1

確實。通常它會被重命名爲'get()'。 – GManNickG 2009-08-14 07:04:38

+0

是否運算符[]應該返回一個引用? – navigator 2009-08-14 08:28:27

2

您可以使用a.operator [] <INT>(1); 但你爲什麼要這樣?

1

這可能不是最佳的解決方案,但你可以直接調用運營商這樣:

class MyClass { 
public: 
    template<class T> 
    T operator[](unsigned int) { 
     // do something 
     return T(); 
    } 
}; 

int main(int argc, char* argv[]) { 
    MyClass test; 
    test.operator[]<int>(0); 
    //test<int>[0]; // doesn't compile, as you mentioned 
    return 0; 
}
+0

這真的很不值得回答。當我輸入這些信息時,我一直看到發佈的答案,而且所有答案都幾乎相同。我想我只是不夠快:) – John 2009-08-14 07:03:22

1

如果您需要:

a.operator[](3);

我用下面的測試試過這種以g ++定義運算符[]然後可能在類級別定義模板。事情是這樣的:

template<class T> 
class C 
{ 
public: 
    T operator[](int n) 
    { 
     return T(); 
    } 
}; 

int main() 
{ 
    C<int> c; 

    int x = c[0]; 

    return 0; 
} 
+0

我需要它在一個類,通過一個實例處理一堆不同類型,而不是一堆處理自己的實例的專門類。我想我只需要去Object.func ()表單! – Scott 2009-08-14 07:01:26

0

我想出哪裏,這將需要一個例子很難(你能不能只超載操盤手?),但這裏是我的想法呢:

由於不能對模板化的運算符使用中綴運算符語法,因此您可能需要在調用運算符之前,在之前執行模板實例化。代理可能是一種做到這一點的方法。

class some_class { 
private: 
    template<class T> class proxy { 
    some_class* that_; 
    public: 
    proxy(some_class* that) : that_(that) {} 
    T& operator[](std::size_type idx) {return that->get<T>(idx);} 
    }; 

    template<class T> class const_proxy { 
    some_class* that_; 
    public: 
    proxy(const some_class* that) : that_(that) {} 
    const T& operator[](std::size_type idx) const {return that->get<T>(idx);} 
    }; 

    template< typename T >  proxy<T> get_array()  {return proxy<T>(this);} 
    template< typename T > const_proxy<T> get_array() const {return proxy<T>(this);} 

    template< typename T >  T& get(std::size_t idx)  {/* whatever */} 
    template< typename T > const T& get(std::size_t idx) const {/* whatever */} 
}; 

// This is a lousy use case. 
// Did I already say I have a hard time imagining how to use this? 
template< typename T > 
void f(some_class& some_object, sid::size_t idx) 
{ 
    T& = some_object.get_array<T>()[idx]; 
} 
4

Boost.Program_options使用這個整齊的語法:

int& i = a["option"].as<int>(); 

這與像這樣實現的:

class variable_value 
{ 
public: 
    variable_value(const boost::any& value) : m_value(value) {} 

    template<class T> 
    const T& as() const { 
     return boost::any_cast<const T&>(m_value); 
    } 

    template<class T> 
    T& as() { 
     return boost::any_cast<T&>(m_value); 
    } 

private: 
    boost::any m_value; 
}; 

class variables_map 
{ 
public: 
    const variable_value& operator[](const std::string& name) const 
    { 
     return m_variables[name]; 
    } 

    variable_value& operator[](const std::string& name) 
    { 
     return m_variables[name]; 
    } 

private: 
    std::map<std::string, variable_value> m_variables; 
}; 

你能適應這樣的想法,以滿足自己的需要。