標籤:

一個關於C++模板的問題?

有一個類模板如下:

#include &

template&
class Test
{
public:
Test& funA()
{
cout &<&< "In funA()" &<&< endl; return Test&();
}
// other functions...
};

若T為int,double等類型,則funcA()的定義如上所述,現在想針對T為複數類型complex&時,funcA()的實現有所不同,其它成員函數不變。目前能想到的解決辦法是偏特化Test類,如下:

template&
class Test&&>
{
public:
Test&&> funA()
{
cout &<&< "In funA():complex" &<&< endl; return Test&&>();
}
// other functions...
};

但是若採用偏特化的方法,funA()以外的函數還要原封不動地copy過來,感覺太笨了,不知有沒有其它較好的實現方法?初學C++望各位大神不吝賜教!!!


寫一個單獨的類Shit,裡面就只有你要偏特化的函數,然後你偏特化這個Shit類,最後Test::funA調用Shit::funA,需要訪問什麼數據就friend一下。


我大概想到了兩種方法(得,看完輪子叔的回答才發現最正常的那種方法沒想到,逃)

先寫幾個helper classes

template&
struct is_complex : std::false_type
{};

template&
struct is_complex&&> : std::true_type
{};

第一種,需要C++11,這個技術叫SFINAE

template&
class Test
{
public:
template&::value, int&>::type = 0&>
Test& funA()
{
std::cout &<&< "complex&
";
return *this;
}
template&::type = 0&>
Test& funA()
{
std::cout &<&< "T "; return *this; } // other functions... };

第二種,需要C++17

template&
constexpr bool is_complex_v = is_complex&::value;

template&
class Test
{
public:
using self = Test&;
self funA()
{
if constexpr (is_complex_v&)
{
cout &<&< "In funA():complex" &<&< endl; } else { cout &<&< "In funA()" &<&< endl; } } // other functions... };


用不著浮蓮子,這裡用繼承更直接。公用部分寫到 TestBase 里。

template &
class TestBase {
/* Common Code */
};

template &
struct is_complex : std::false_type {};

template &
struct is_complex&&> : std::true_type {};

template &
class TestImpl;

template &
using Test=TestImpl&::value&>;

template &
class TestImpl& : public TestBase& {
public:
Test& funcA() const {
std::cout&<&<"is complex"&<&{};
}
};

template &
class TestImpl& : public TestBase& {
public:
Test& funcA() const {
std::cout&<&<"is not complex"&<&{};
}
};

gcc 自帶的頭文件里有不少類似的寫法……


我想,輪子哥是這個意思

#include &
#include &

template&
class TestHelper;

template&
class Test{
friend class TestHelper&;
public:
Test& funA(){
return TestHelper&::TestFunA(this);
}
};

template&
class TestHelper{
friend Test&;
static inline Test& TestFunA(Test&*){
std::cout&<&<"funA"&<&();
}

};

template&
class TestHelper&&>{
friend Test&&>;
static inline Test&&> TestFunA(Test&&>*){
std::cout&<&<"funA for complex"&<&&>();
}
};

int main(){
Test& tf;
Test&&> tcf;
tf.funA();//funA
tcf.funA();//funA for complex
return 0;
}


可以用 constexpr if


推薦閱讀:

關於c++模板推導失敗,這是編譯器的bug嗎?
《深度探索c++對象模型》,C語言有沒有類似的書,講解C語言低層細節及編譯器所做工作?
計算機語言是有局限性的么?
如何理解c++中的引用摺疊?
extern C裡面能有C++代碼嗎?

TAG:CC |