簡體   English   中英

類型轉換或轉發功能(取決於輸入類型)

[英]Function for type converting or forwarding (depending on input type)

我有一段代碼是這樣的:

void some_func(SomeType st) {
    some_stuf...
    dosomething( st.myStruct() );
    some_more_stuff...
}

SomeType::myStruct的類型為MyStruct 這個SomeType經歷了一些序列化,並且在通信通道的另一端,我反序列化了SomeType ,它被稱為AlmostSomeType ,它具有相同的字段,除了myStruct的類型為std::string (不能反序列MyStruct )。

MyStruct可以從std::string創建。

現在,為了不創建some_func (DRY!)的其他版本,我將這樣做:

template< typename Type >
void some_func( Type type ) {
    some_stuf...
    dosomething( getMyStruct( type.myStruct() ) ); 
    // or even something like: 
    const MyStruct& myStruct = getMyStruct( type.myStruct() );
    more calls to myStruct...
    some_more_stuff...
}

getMyStruct如下所示:

template< typename T >
T getMyStruct( T&& aT )
{ return aT; }

MyStruct getMyStruct( std::string myStructString )
{ return MyStruct( myStructString ); }

現在,這就是我所知道/想的:

  1. 我知道它看起來不太好,但是現實生活中的項目看起來不太好。 我無法修改AlmostSomeTypeSomeType
  2. 我不想增加任何額外的開銷,這就是為什么我使用通用引用來處理任何類型的MyStruct (引用,const引用等)和std::string版本的原因。
  3. 瑕疵? 如果有人將MyStructstd::string之外的任何東西放入getMyStruct則如果MyStruct參數構造函數不是explicit則它可能會通過。
  4. 我用MyStruct完成了簡單的測試, MyStruct包括所有需要的MyStruct和賦值運算符,使用-O2編譯了代碼,並得到了我期望的結果,即未調用copy-ctors。

如果這是正確的方法,那么我想聽聽您的意見,即,如果此函數模板方法可行,或者我應該注意一些注意事項。 我知道我在指望編譯器優化,但是,嘿! 您不能僅依賴語言語義。

環境:gcc(4.7.2),-std = c ++ 11,-O2

編輯

我正在使用的一些示例代碼:

struct MyStruct
{
    MyStruct() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
    explicit MyStruct( std::string a ) : dummy_(a.size()) { std::cout << __PRETTY_FUNCTION__ << "\n"; }
    MyStruct( const MyStruct& aOther ) : dummy_(aOther.dummy_) { std::cout << __PRETTY_FUNCTION__ << "\n"; }
    MyStruct( MyStruct&& aOther ) : dummy_(std::move(aOther.dummy_)){ std::cout << __PRETTY_FUNCTION__ << "\n"; } 
    ~MyStruct() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
    MyStruct& operator=( const MyStruct& aOther ) { std::cout << __PRETTY_FUNCTION__ << "\n"; return *this; }
    MyStruct& operator=( MyStruct&& aOther ) { std::cout << __PRETTY_FUNCTION__ << "\n"; return *this; }

    double dummy_;
    char cdummy_[100];
};

struct MyAggregate
{
    MyStruct myStruct_;
    std::string myString_;

    const MyStruct& myStruct() { return myStruct_; }
    const std::string& myString() { return myString_; }

    MyAggregate() :myString_("four") { myStruct_.dummy_ = 5.5; }
};


int main()
{
    MyAggregate myAggregate;
    std::cout << "---\n";
    const MyStruct& ms1 = getMyStruct( myAggregate.myStruct_ );
    std::cout << "---\n";
    const MyStruct& ms2 = getMyStruct( myAggregate.myString_ );
    std::cout << "---\n";
    const MyStruct& ms3 = getMyStruct( myAggregate.myStruct() );
    std::cout << "---\n";
    const MyStruct& ms4 = getMyStruct( myAggregate.myString() );
    std::cout << "---\n";
    return 0;
}

我得到的輸出:

MyStruct::MyStruct()
---
T getMyStruct(T&&) [with T = MyStruct&]
---
MyStruct getMyStruct(std::string)
MyStruct::MyStruct(std::string)
---
T getMyStruct(T&&) [with T = const MyStruct&]
---
MyStruct getMyStruct(std::string)
MyStruct::MyStruct(std::string)
---
MyStruct::~MyStruct()
MyStruct::~MyStruct()
MyStruct::~MyStruct()

解決方案中有過多的字符串副本(當您按值傳遞時)。 為什么不提取字符串的特殊情況然后分開處理呢?

template<typename T, typename = 
   typename enable_if<!is_same<decay_t<T>,string>::value>::type >
decltype(auto) getMyStruct( T&& aT )
{ return aT; }

template<typename T, typename = 
    typename enable_if<is_same<decay_t<T>,string>::value>::type >
MyStruct getMyStruct (T &&aT)
{ return MyStruct (aT);}

我在上面放了一些std::前綴,使代碼看起來更整潔。

在GCC 5.1上,輸出為:

MyStruct::MyStruct()
---
decltype(auto) getMyStruct(T&&) [with T = MyStruct&; <template-parameter-1-2> = void]
---
MyStruct getMyStruct(T&&) [with T = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void]
MyStruct::MyStruct(std::__cxx11::string)
---
decltype(auto) getMyStruct(T&&) [with T = const MyStruct&; <template-parameter-1-2> = void]
---
MyStruct getMyStruct(T&&) [with T = const std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void]
MyStruct::MyStruct(std::__cxx11::string)
---
MyStruct::~MyStruct()
MyStruct::~MyStruct()
MyStruct::~MyStruct()

我用~/x86-toolchain-5.1/bin/g++ mystr.cpp --std=c++14

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM