#include <iostream>
#include <vector>
#include <utility>
template<typename T, typename U, typename A1, typename A2>
decltype(std::declval<T>() * std::declval<U>() + std::declval<T>() * std::declval<U>())
dot_product( std::vector<T, A1> const& lhs, std::vector<U, A2> const& rhs )
{
decltype(std::declval<T>() * std::declval<U>() + std::declval<T>() * std::declval<U>()) sum = 0;
for( std::size_t i = 0; i < lhs.size() && i < rhs.size(); ++i ) {
sum += lhs[i] * rhs[i];
}
return sum;
}
template<typename LHS>
struct half_dot {
LHS lhs;
half_dot( LHS&& lhs_ ):lhs(std::forward<LHS>(lhs_)) {}
template<typename RHS>
decltype( dot_product( std::declval<LHS>(), std::declval<RHS>() ) )
operator*( RHS&& rhs ) const {
return dot_product( std::forward<LHS>(lhs), std::forward<RHS>(rhs) );
}
};
struct dot_t {};
template<typename LHS>
half_dot<LHS> operator*( LHS&& lhs, dot_t ) {
return {std::forward<LHS>(lhs)};
}
static dot_t dot;
int main() {
std::vector<int> foo = {1,2,3};
std::vector<int> bar = {3,2,1};
std::cout << (foo *dot* bar) << "\n";
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dXRpbGl0eT4KCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSBVLCB0eXBlbmFtZSBBMSwgdHlwZW5hbWUgQTI+CiAgICBkZWNsdHlwZShzdGQ6OmRlY2x2YWw8VD4oKSAqIHN0ZDo6ZGVjbHZhbDxVPigpICsgc3RkOjpkZWNsdmFsPFQ+KCkgKiBzdGQ6OmRlY2x2YWw8VT4oKSkKICAgIGRvdF9wcm9kdWN0KCBzdGQ6OnZlY3RvcjxULCBBMT4gY29uc3QmIGxocywgc3RkOjp2ZWN0b3I8VSwgQTI+IGNvbnN0JiByaHMgKQogICAgewogICAgICBkZWNsdHlwZShzdGQ6OmRlY2x2YWw8VD4oKSAqIHN0ZDo6ZGVjbHZhbDxVPigpICsgc3RkOjpkZWNsdmFsPFQ+KCkgKiBzdGQ6OmRlY2x2YWw8VT4oKSkgc3VtID0gMDsKICAgICAgZm9yKCBzdGQ6OnNpemVfdCBpID0gMDsgaSA8IGxocy5zaXplKCkgJiYgaSA8IHJocy5zaXplKCk7ICsraSApIHsKICAgICAgCXN1bSArPSBsaHNbaV0gKiByaHNbaV07CiAgICAgIH0KICAgICAgcmV0dXJuIHN1bTsKICAgIH0KICAgIHRlbXBsYXRlPHR5cGVuYW1lIExIUz4KICAgIHN0cnVjdCBoYWxmX2RvdCB7CiAgICAgIExIUyBsaHM7CiAgICAgIGhhbGZfZG90KCBMSFMmJiBsaHNfICk6bGhzKHN0ZDo6Zm9yd2FyZDxMSFM+KGxoc18pKSB7fQogICAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBSSFM+CiAgICAgIGRlY2x0eXBlKCBkb3RfcHJvZHVjdCggc3RkOjpkZWNsdmFsPExIUz4oKSwgc3RkOjpkZWNsdmFsPFJIUz4oKSApICkKICAgICAgb3BlcmF0b3IqKCBSSFMmJiByaHMgKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIGRvdF9wcm9kdWN0KCBzdGQ6OmZvcndhcmQ8TEhTPihsaHMpLCBzdGQ6OmZvcndhcmQ8UkhTPihyaHMpICk7CiAgICAgIH0KICAgIH07CiAgICBzdHJ1Y3QgZG90X3Qge307CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBMSFM+CiAgICBoYWxmX2RvdDxMSFM+IG9wZXJhdG9yKiggTEhTJiYgbGhzLCBkb3RfdCApIHsKICAgICAgcmV0dXJuIHtzdGQ6OmZvcndhcmQ8TEhTPihsaHMpfTsKICAgIH0KICAgIHN0YXRpYyBkb3RfdCBkb3Q7CiAgICAgIAogICAgaW50IG1haW4oKSB7CiAgICAgIHN0ZDo6dmVjdG9yPGludD4gZm9vID0gezEsMiwzfTsKICAgICAgc3RkOjp2ZWN0b3I8aW50PiBiYXIgPSB7MywyLDF9OwogICAgICBzdGQ6OmNvdXQgPDwgKGZvbyAqZG90KiBiYXIpIDw8ICJcbiI7CiAgICB9