Rub*_*ens 1 c++ operator-overloading variadic-templates
我试图将我的一些函数更改foo()为operator<<(),只是为了让一些“半 C/半 C++”代码看起来更像 C++。但是,发生了,我被困在了以下转换步骤:
template <class... T>
inline const size_t foo(const T&... data) {
return sizeof...(T);
}
struct bar {
template <class... T>
inline const size_t operator<<(const T&... data) {
return sizeof...(T);
}
};
int main(int argc, char *argv[]) {
bar a;
std::cout << ">>> length " << foo(1, 2, 3) << std::endl;
std::cout << ">>> length " << (a << 1 << 2) << std::endl;
std::cout << ">>> length " << (a << 1 << 2 << 3) << std::endl;
std::cout << ">>> length " << (a << 1 << 2 << 3 << 4) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
从输出:
$ ./a.out
>>> length 3
>>> length 4
>>> length 32
>>> length 512
Run Code Online (Sandbox Code Playgroud)
我得出结论,第一次计算是在 上执行的a << 1,随后的值会相应地移动。然而,我没有看到如何重写foo(),以便为用户提供一个operator<<() 界面struct bar——当然,不改变foo()语义。
如果无法class T...作为参数传递给operator<<(),该函数自然会比 效率低foo(),因为它会被多次调用。是否有任何合理的 C++ 构造,或者坚持foo()是这里唯一/最好的选择?
上下文:
这些foo()功能是网络通信的发送者/接收者。我认为最好提供一个更“C++”的接口,带有发送者/接收者流,可写/可读的使用<<和>>操作符——而不是使用常规函数foo(...)。
语言正在做你要求它做的事情。
对于结合性,以下是等效的(<<并且>>是从左到右结合的):
a << 1 << 2
(a << 1) << 2
Run Code Online (Sandbox Code Playgroud)
该调用a << 1调用您的用户定义的运算符,后者又返回一个size_t. 这就是为什么 next call 的类型如下:(size_t << int这是一个简单的按位移位)。
您需要使用表达式模板。想法如下(此处为现场示例):
template<typename... args>
struct stream_op
{
};
template<typename... A, typename B>
stream_op<A..., B> operator<<(stream_op<A...> a, B b)
{
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)
因此,发生以下情况(a作为 a stream_op<>):
a << 1 << 2
------
|
v
-------------------------------------------
stream_op<int> operator<<(stream_op<>, int) << 2
-------------- ---
| |
| +---------------------------+
v v
-------------- ---
stream_op<int> << int
-------------- ---
| |
| +---------------------------+
+----------------------------+ |
v v
-------------- ---
stream_op<int,int> operator<<(stream_op<int>, int)
------------------
|
v
------------------
stream_op<int,int> // <- Expected result
Run Code Online (Sandbox Code Playgroud)
然后你只需要放置一个方法来转换stream_op为 int (或任何你想要的)。
关于性能的注意事项:使用这些表达式模板,部分数据被编码在类型中,因此通常它应该与直接调用foo(...).