2015-02-05 31 views
3

我想要實例我可以使用decltype(或類似的東西)進行顯式模板實例化而不簽名重複嗎?

template<typename T> void foo(
    T& t, 
    SomeType some_parameter, 
    AnotherType another_parameter, 
    EtcType yet_another_parameter, 
    AsYouCanTell this_is_a_very_long_signature); 

就是用長簽名的功能。現在,我知道如何做到這一點:

template void foo<int>(
    int& t, 
    SomeType some_parameter, 
    AnotherType another_parameter, 
    EtcType yet_another_parameter, 
    AsYouCanTell this_is_a_very_long_signature); 

但我必須複製簽名。另外,如果想要針對5種不同類型的特定實例 - 我可以複製5次嗎?無厘頭......

我想也許我可以寫

template decltype(foo<int>); 

,但由於某種原因,這是行不通的。爲什麼?

+1

他沒有試圖做任何這些事情。他正試圖顯式實例化這個模板。 – Puppy 2015-02-05 23:25:41

+1

您不需要函數參數的名稱,順便說一下:'template foo (int&,SomeType,AnotherType,EtcType,AsYouCanTell);'。您可以使用類型別名進一步縮短類型名稱。 – dyp 2015-02-05 23:26:16

+0

我不知道你是否可以濫用C++ 14的變量模板來做到這一點:而不是顯式實例化函數模板,也許顯式實例化引用函數模板的變量模板可能就足夠了。可能的是,靜態數據成員和別名模板可以實現類似的功能,但我不確定這一點。 – dyp 2015-02-05 23:32:43

回答

6

它的實際工作,但語法是不同的:

template 
decltype(foo<int>) foo<int>; 

decltype給你一個但顯式實例需要聲明這是一種後跟名稱。

試用GCC 4.9.1;它按預期工作,即使使用-pedantic標誌,也不會發出任何警告。

+0

如果你還沒有提供實現,這個答案提供了預期的編譯器錯誤:(clang 3.5.0)'錯誤:未定義函數模板'foo''的顯式實例化。我嘗試了另一種自己的解決方案,但是當缺少實現時,它只給出了鏈接器錯誤。 – 2015-02-06 00:12:33

+1

我不願意說這完全是合法的,因爲[dcl.fct]/12 *「函數類型的typedef可能用來聲明一個函數,但不能用來定義一個函數。」*但我認爲儘管答案中的陳述是一個*明確的實例化定義*,但我認爲它不是一個函數wrt [dcl.fct]/12的定義。 – dyp 2015-02-06 00:14:13

0

我認爲這是一個宏觀的好,合法使用:

#define INSTANTIATE_FOO(type) \ 
    template void foo<type>(type& t, \ 
        SomeType some_parameter, \ 
        AnotherType another_parameter, \ 
        EtcType yet_another_parameter, \ 
        AsYouCanTell this_is_a_very_long_signature); 

INSTANTIATE_FOO(int) 
INSTANTIATE_FOO(float) 
INSTANTIATE_FOO(my_little_dragon) 

#undef INSTANTIATE_FOO 
+0

定義宏時,您仍然至少複製了一次簽名。如果你試圖避免重複,它會變成一個複雜的宏... – einpoklum 2015-02-05 23:31:59

1

沒有,因爲超載

template<typename T> void foo(T& t, 
        SomeType some_parameter, 
        AnotherType another_parameter, 
        EtcType yet_another_parameter, 
        AsYouCanTell this_is_a_very_long_signature); 
template<template T> void foo(T& t); //completely unrelated function 
template<template T> void foo(char); //another completely unrelated function 

現在想象一下,什麼是顯式實例第一所需的最小信息的一?那麼,你需要完整的簽名來消除歧義,所以

explicit int foo(int&, SomeType, AnotherType, EtcType, AsYouCanTell) 

是理論上的最小信息量。那麼,C++實際上需要具有非常小的開銷:

template void foo<int>(int& t, SomeType, AnotherType, EtcType, AsYouCanTell); 

如果你不想輸入所有這一切,那麼宏的康拉德的建議是要走的路。

+0

但我沒有任何這些重載的功能。 – einpoklum 2015-02-05 23:45:29

+0

該語言必須使用明確實例化的格式,這將是有效的_不管其他函數是什麼。他們是否真的存在是無關緊要的。它們可以存在,並且語法必須支持它。 – 2015-02-06 00:09:39

3

它實際上比@更簡單5gon12eder建議:

template decltype(foo<int>) foo; 

,但肯定的,它就像他說的 - decltype()僅提供了類型和簽名是不是一個真正的類型。

編輯:當模板具有價值的參數,而不僅僅是類型這不工作,所以如果我們有

template <typename T, unsigned Val> bar(T t); 

然後

template decltype(bar<int, 1>) bar; 

將無法​​編譯,而

template decltype(bar<int, 1>) bar<int, 1>; 

會。

+1

我很驚訝,這工作。這是否意味着第二個「foo」的推導類型?這很酷。 – 5gon12eder 2015-02-05 23:55:43

+0

@dyp但它必須被編譯爲正確的模板實例化的錯位名稱,否則鏈接程序無法找到定義。我查看了彙編代碼,它提供的是否提供''完全相同。 – 5gon12eder 2015-02-05 23:58:17

+0

@dyp模板參數顯然必須從類型中推導出來。 – Columbo 2015-02-05 23:59:00

相關問題