原型

2015-06-15 34 views
1

下面編譯運行的C++模板等價和按預期執行:原型

#include <cstdlib> 
#include <cstring> 
#include <iostream> 
#include <type_traits> 

class Freaky { 
public: 
    template< 
     typename UNSIGNED_TYPE, 
     typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X = 0 
    > 
    static UNSIGNED_TYPE copyThing(int x) ; 
}; 

template< 
    typename UNSIGNED_TYPE, 
    typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X 
> 
UNSIGNED_TYPE Freaky::copyThing(int x) { 
    UNSIGNED_TYPE r(0); 
    std::memcpy(&r,&x,sizeof(int));//Please ignore. Not the point of the question... 
    return r; 
} 

int main(int argc, char*argv[]) { 
    std::cout << "The answer is ... " << 
     Freaky::copyThing<unsigned long>(10)<<std::endl; 
    return EXIT_SUCCESS; 
} 

標本輸出(實際的輸出可取決於字節序和整數大小):

The answer is .... 10 

以下韓元對copyThing()實施的原型進行編譯和投訴與在類中聲明的不匹配。

#include <cstdlib> 
#include <cstring> 
#include <iostream> 
#include <type_traits> 

class Freaky { 
public: 
    template< 
     typename UNSIGNED_TYPE, 
     typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X = 0 
    > 
    static UNSIGNED_TYPE copyThing(int x) ; 
}; 

template< 
    typename UNSIGNED_TYPE, 
    typename std::enable_if<(sizeof(int)<=sizeof(UNSIGNED_TYPE)),int>::type X 
> 
UNSIGNED_TYPE Freaky::copyThing(int x) { 
    UNSIGNED_TYPE r(0); 
    std::memcpy(&r,&x,sizeof(int));//Please ignore. Not the point of the question... 
    return r; 
} 

int main(int argc, char*argv[]) { 
    std::cout << "The answer is ... " << 
     Freaky::copyThing<unsigned long>(10)<<std::endl; 
    return EXIT_SUCCESS; 
} 

兩者之間的唯一區別是,sizeof(UNSIGNED_TYPE)>=sizeof(int)已被替換在執行sizeof(int)<=sizeof(UNSIGNED_TYPE)

顯然,兩種說法都語義等同。 我在哪裏可以找到模板原型如何被確定爲相等的正式定義?

這顯然詞彙等價,而不是語義等價的某一水平。

+0

貌似enable_if在這兩種情況下的不同。可能他們應該完全一樣。而且,'> ='的倒數不應該是'<'? – KDM

+0

@KDM你的意思是'> ='的補碼是'<'。注意我已經交換了術語和> =的含義。讀取'TYPE大於或等於int',另一個'int小於或等於類型'。他們有相同的含義 - 我想要的。 (A> = B)==(B <= A)。總是(當操作符被定義爲任何服從傳統的關係語義時......)。 – Persixty

回答

2

我無法找到的時候類模板(或類模板及其成員的亂線定義符)重聲明是相同的明確指定標準的任何部分。

編譯器實際上遵循函數模板的重聲明的規則,如在C++ 11 14.5.6.1/5+6指定:

5涉及模板參數兩個表達式被認爲等效如果兩個功能除[template parameter renaming]外,包含表達式的定義將滿足一個定義規則(3.2)。 6兩個函數模板被等效如果它們在相同的範圍中聲明,具有相同的名稱,具有相同的模板的參數列表,並有返回類型和等同使用上述規則來比較涉及模板參數表達式參數列表。

儘管如此,我找不到任何規則使其適用於用於重新聲明類模板的非類型模板參數類型中的表達式。

+0

謝謝你。 – Persixty