2012-01-31 61 views
2

在部分特化模板參數中使用模板參數時,是否有辦法解決標準的侷限性?我想使它工作的代碼是這樣的:涉及模板參數的模板參數

template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0> 
class a{}; 

template<typename L> 
class a<L, sizeof(L)-1>{}; 
+1

從代碼中不清楚你的意思。假設代碼可以編譯,基本上(如果我理解正確的話)定義一個帶有兩個參數類型和偏移量的模板,如果用戶沒有提供,其中第二個參數默認爲'sizeof(L)-1' ...很簡單:'template class a {};'但我明白那不是你的意圖。當問你應該說明你的意思,而不僅僅是非工作代碼。當你談論你知道不支持的代碼時更是如此。 – 2012-01-31 13:17:51

回答

4

因爲它是C++ 11,你可以簡單地使用static_assert的一般條件。對於sizeof(L)-1的事情,你需要使用enable_if技巧,因爲它需要一些專門的東西。例如:

#include <cstdlib> 
#include <type_traits> 
#include <cstdio> 

template <typename L, size_t offset, typename = void> 
class a 
{ 
    static_assert(offset < sizeof(L), "something's wrong"); 
public: 
    void f() 
    { 
     printf("generic\n"); 
    } 
}; 

template <typename L, size_t offset> 
class a<L, offset, typename std::enable_if<offset == sizeof(L)-1>::type> 
{ 
    // note: the static_assert is *not* inherited here. 
public: 
    void f() 
    { 
     printf("specialized\n"); 
    } 
}; 

int main() 
{ 
    static_assert(sizeof(int) == 4, "oops"); 
    a<int, 3> x; 
    a<int, 2> y; 
    x.f(); 
    y.f(); 
    return 0; 
} 

演示:http://ideone.com/D2cs5

+1

你的代碼不會編譯,事實上真正的問題(模板參數中的'sizeof(L)-1')仍然存在。 – 2012-01-31 13:02:05

+0

@LorenzoPistone:檢查更新。 – kennytm 2012-01-31 13:12:13

+0

太好了。還有一個問題:在這裏,我是否認爲類模板與主類中的調用相匹配,但是專用版本是首選的,因爲它確實是專用的? – 2012-01-31 13:46:50

2

我不知道這是否是你的意思。這是你可以選擇不同的實現,如果第二個模板arguemnt第一個模板參數的大小相匹配 - 1.

template<typename L, size_t offset> 
class aImplMatch 
{ // choose this if offset == sizeof(L) - 1 
    L v; 
}; 

template<typename L, size_t offset> 
class aImpl 
{ 
    L v; 
    char off[offset]; 
}; 

template<typename L, size_t offset, size_t i> 
struct SelectImpl{}; 

template<typename L, size_t offset> 
struct SelectImpl<L, offset, 0> { typedef aImplMatch<L, offset> Result; }; 

template<typename L, size_t offset> 
struct SelectImpl<L, offset, 1> { typedef aImpl<L, offset> Result; }; 

template<typename L, size_t offset> 
class a 
{ 
    enum {I = offset == sizeof(offset) - 1 ? 0 : 1 }; 
    typedef typename SelectImpl<L, offset, I>::Result Impl; 
    Impl impl; 
}; 

也許它可以做的更好/更容易,這是我的第一個想法......