2009-05-26 160 views
3

我需要一個C++模板,在給定類型和該類型對象的情況下,它可以根據類型是否爲整數來做出決定,同時能夠訪問實際對象。我試過這個C++模板專業化問題

template <typename T, T &N> 
struct C { 
    enum { Value = 0 }; 
}; 

template <int &N> 
struct C<int, N> { 
    enum { Value = N }; 
}; 

但它不起作用。有什麼辦法可以達到類似的目的嗎?

編輯

我試圖實現了這樣的事情,會發生在編譯時說:

if (type is int) { 
    return IntWrapper<int_value> 
else { 
    return type 
} 

實際上,你可以通過指針或引用對象模板實例,像這樣:

struct X { 
    static const int Value = 5; 
}; 

template <X *x> 
struct C { 
    static const int Value = (*x).Value; 
}; 

X x; 

std::cout << C<&x>::Value << std::endl; // prints 5 

但顯然這一切都完成了初始化模板通過推斷環x的類型,並且x也需要全局聲明。沒有用,我想要做的事情,我認爲在編譯時畢竟是不可能的。

+0

聽起來你需要一個函數模板,因爲類模板需要你明確指定模板類型參數。你能發佈一個用法示例來澄清你想要做什麼嗎? – 2009-05-26 13:29:35

+0

@j_random_hacker:您可以將模板留空並且有專門的類...您不必指定模板類型。 – Partial 2009-09-08 21:13:44

回答

7

您試圖執行的操作不是有效的C++模板。你不能使用任意對象作爲模板參數,所有你可以使用的都是類型,整型文本以及某些特殊情況下的字符串文字。

+0

和布爾值以及 – 2009-05-26 13:56:05

+0

不知道爲什麼有人低估了你,但我希望更多將有助於讓你在上面... – Pieter 2009-05-26 14:12:35

3

template <typename T> struct A 
{ 
    enum { Value = false }; 
}; 
template <> struct A<int> 
{ 
    enum { Value = true }; 
}; 

那麼這個怎麼樣:


template <typename T> struct A 
{ 
    T value_; 
    A() : value() {} 
    enum { is_int = false }; 
}; 
template <> struct A<int> 
{ 
    int value_; 
    explicit A(int v) : value_(v) {} 
    enum { is_int = true }; 
}; 
2

你可以這樣說:

template<typename T, int val> 
struct Test 
{ 
    enum {Value = 0}; 
}; 

template <int val> 
struct Test<int, val> 
{ 
    enum {Value = val}; 
}; 




int main(int argc,char *argv[]) 
{ 
    int v = Test<int,1>::Value; 
} 
3

除了這個以外的帖子:你並不需要使用enum {} -hack更多:

template<typename T, int val> 
struct Test { 
    static const int Value = 0; 
}; 

template <int val> 
struct Test<int, val> { 
    static const int Value = val; 
}; 


int main(int argc,char *argv[]) { 
    const int v = Test<int,1>::Value; 
} 
0

簡單修復你R代碼裏面 - 鬆散的參考:在模板參數使用參考

template <typename T, T N> 
struct C { 
    enum { Value = 0 }; 
}; 

template <int N> 
struct C<int, N> { 
    enum { Value = N }; 
}; 

是沒有意義的,因爲反正你不實際傳遞參數的任何地方。

4

也許一個簡單的重載模板方法適用於你的情況?

template<typename T> 
void doSomething(const T& x) 
{ 
    // ... 
} 
void doSomething(int x) 
{ 
    // ... 
} 
2

我需要一個C,給定一個 類型和類型的對象++模板,它 可以做出決定的基礎的類型是否 是一個整數或沒有,而 能夠訪問實際的 對象。

您可以根據類型是否爲整數來做出決定,問題是不可能用任何類型的對象聲明模板。所以關於如何決定一個類型是一個整數的問題是沒有意義的。

注意,在所有回答您的原始模板被整齊地改爲

template < typename T, int > 
class C {}; 

template< typename T, T > 
class C {}; 

代替不過,雖然C<int, 5>是一個完全有效的聲明,這不是一個任意的情況下類型T,例如C<float, 5.>將導致編譯器錯誤。

你可以發佈你想要達到的目標嗎?

並記錄在案,如果第二個模板參數始終是一個int,而您只是想,如果類型爲一個整數類型取它的價值,而0 otherwhise,你可以簡單地做:

#include <limits> 

template< typename T, int N > 
class C { 
    static const int Value = (std::numeric_limits<T>::is_integer) ? N : 0; 
}; 
5

除非我誤解了你,你想要的是不可能的。在你的例子中,你顯示了一個指針模板參數的無效使用。

template <X *x> 
struct C { 
    static const int Value = (*x).Value; 
}; 

這是無效的,因爲(*x).Value必須是一個常量表達式爲它能夠初始化Value。當作爲X::Value使用時,類X內的當然Value可以作爲常量表達式。但是這一次,這不是因爲它涉及一個指針(引用在常量表達式中同樣無效)。

綜上所述,你不能做到這一點:

Magic<T, someT>::type 

,並期望::type爲T,如果T不是int和IntWrapper<someT>否則,因爲T只能是一個枚舉,整數,指針或引用類型。在後兩種情況下,你不會得到指針指向的任何東西的「價值」,或者參考編號編譯時間如果你對此感到滿意,很容易解決你的問題,我不會告訴你如何(我懷疑你已經知道如何)。

我想你已經把自己變成了解決問題已經變得不可能完成規則的情況。開車回來一些步驟,並告訴我們真正問題,你正試圖解決,當問題仍然允許解決的事情。

0

Template specialization可以實現這樣的(從www.cplusplus.com採取代碼):

// template specialization 
#include <iostream> 
using namespace std; 

// class template: 
template <class T> 
class mycontainer { 
    T element; 
    public: 
    mycontainer (T arg) {element=arg;} 
    T increase() {return ++element;} 
}; 

// class template specialization: 
template <> 
class mycontainer <char> { 
    char element; 
    public: 
    mycontainer (char arg) {element=arg;} 
    char uppercase() 
    { 
     if ((element>='a')&&(element<='z')) 
     element+='A'-'a'; 
     return element; 
    } 
}; 

int main() { 
    mycontainer<int> myint (7); 
    mycontainer<char> mychar ('j'); 
    cout << myint.increase() << endl; 
    cout << mychar.uppercase() << endl; 
    return 0; 
} 

你的情況,你必須通過要在類模板專業化什麼來代替焦炭。現在,我不太清楚你在做什麼,但我希望上面的例子是一個很好的指標,可以幫你做一些模板專業化。

0

我試圖實現了這樣的事情,會發生在編譯時說:

if (type is int) { 
    return IntWrapper<int_value> 
else { 
    return type 
} 

你爲什麼不使用IntWrapper開始與我不知道。如果需要將編譯時整型常量包裝到IntWrapper中,如果它是int?

否則,它看起來有點你試圖用僅在運行時可用的數據實例化模板。