2013-11-25 40 views
3

當我聲明一個類靜態方法時,是否可以使用decltype(或以任何其他類似的樣式)引用當前類?例如,如何在C++ 11中使用decltype引用當前類?

class 
AAA 
{ 
    static AAA const make(); 
}; 

我想使這樣的事情。

class 
AAA 
{ 
    static decltype(*this) const make(); // Not working because there's no `this`. 
}; 

*this用於描述我想要做什麼。我想知道一些decltype()表達式,可以解析爲AAA

如果可能我該怎麼做?

+1

我不知道爲什麼要爲間接的'static decltype(* this)const make()'交換清晰簡潔的'static AAA const make()'形式。可讀性是王道,明確你的類型對你的讀者有很大的幫助。 – cmaster

+0

在這個背後的想法是以特定的「智能」方式將「make」函數添加到整個層次的類中?對於奇怪的循環模板參數模式來說,情況就是如此。如果這只是一個類,我不明白需要派生返回類型,'AAA'會很好(但是,我不明白調用構造函數是什麼問題)。 – Damon

+0

我沒有特定的用例。我突然對此感到好奇,如果這是可能的,我想也許我可以稍後找出一些有趣的應用。在這個問題上,我不主張任何善意的壞主意。我也認爲這不會太有用,但這個問題困擾了我很長時間,所以我決定問這個問題。 – Eonil

回答

2

在C++ 1Y你可以這樣做:

class 
AAA 
{ 
public: 
    static auto make() 
    { 
     return AAA(); 
    } 
}; 

int main() 
{ 
    AAA aaa = AAA::make(); 
} 

,因爲你需要指定返回類型爲make()這不是C++ 11的法律。在C++ 98/03/11中,您可以:

class 
AAA 
{ 
public: 
    typedef AAA Self; 

    static Self make() 
    { 
     return AAA(); 
    } 
}; 

這是低科技,但非常可讀。

<aside>

你應該避免通過值返回const限定的類型。這抑制了有效的移動語義。如果您想避免分配給右值,則創建一個符合&的賦值運算符。

</aside>

0

也許你可以做這樣的事情:

#include<iostream> 

class AAA 
{ 
    int _i; 

    public: 
    AAA(int i): _i(i) {} 

    static auto make(int i) -> typename std::remove_reference<decltype(*this)>::type 
    { 
     return {i}; 
    } 

    void print() 
    { 
     std::cout << _i << std::endl; 
    } 
}; 

int main() 
{ 
    AAA aaa = AAA::make(1); 
    aaa.print(); 
    return 0; 
} 

它編譯於GCC 4.7.2至少:)


EDIT 26/11-13:上面的代碼不是合法的C++,即使它使用gcc編譯,它不會與clang或icpc一起使用。我很抱歉。

+1

用戶hvd已經提出了類似的建議(現已刪除),但不允許:[expr.prim.general]/3關於表達式'this':「它不會出現在可選的* cv-qualifier-seq *之前,並且它不應出現在靜態成員函數聲明中「 – dyp

+0

@DyP:我懷疑可能是這種情況。謝謝,發佈更新。 – Banan

0

剛剛發明使用成員指針的方式,它似乎工作: http://www.tutorialspoint.com/compile_cpp11_online.php?PID=0Bw_CjBb95KQMZHFMdG5SSFBwXzg


    #define self_test(name) \ 
    void dummy__##name(void) {} \ 
    template static T type__##name(void (T::*func)(void)) { return T(); } \ 
    typedef decltype(type__##name(&dummy__##name)) self__##name; \ 
    static void test(void) { self__##name::print(); } 

    struct T1 { 
     self_test(X); 
     static void print() { printf("this is T1\n"); } 
    }; 

    struct T2 { 
     self_test(X); 
     static void print() { printf("this is T2\n"); } 
    }; 

    int main() { 
     T1::test(); 
     T2::test(); 
    } 

這也不是完美的,它需要-fpermissive用gcc, 編譯但至少GCC/VS /英特爾全都編譯它,它工作。 另外事實上,gcc/mingw甚至不需要爲此付費。

相關問題