【发布时间】:2015-08-04 22:33:38
【问题描述】:
我有一段代码可以做这样的事情:
void some_func(SomeType st) {
some_stuf...
dosomething( st.myStruct() );
some_more_stuff...
}
这个SomeType::myStruct 的类型是MyStruct。这个SomeType 经历了一些序列化,在通信通道的另一端我得到反序列化SomeType,它被称为AlmostSomeType,它具有相同的字段,除了myStruct 的类型是std::string(它不能' t 被反序列化为MyStruct)。
MyStruct 可以从std::string 创建。
现在,为了不创建 some_func(干!)的其他版本,我将这样做:
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 ); }
现在这是我所知道/认为的:
- 我知道它看起来不好看,但现实生活中的项目看起来并不好看。我无法修改
AlmostSomeType和SomeType。 - 我不想产生任何额外的开销,这就是我使用 通用参考 的原因,它可以处理任何类型的
MyStruct(参考、常量参考等)和std::string版本字符串。 - 缺陷?如果有人将
MyStruct或std::string以外的任何内容放入getMyStruct,如果MyStruct的参数构造函数不是explicit,它可能会通过。 - 我使用
MyStruct进行了简单的测试,其中包含所有需要的 ctor 和赋值运算符,使用-O2编译代码并得到了我预期的结果,即没有调用任何复制 ctor。
我想听听你的意见,如果这是正确的方法,即如果这个函数模板方法是好的,或者有一些我应该注意的警告。我知道我在考虑编译器优化,但是,嘿!你不能只依赖语言语义。
环境: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()
【问题讨论】: