I was experimenting with a simple code for calculating cosine similarity:
#include <iostream>
#include <numeric>
#include <array>
#include <cmath>
float safe_divide(const float& a, const float& b) { return b < 1e-8f && b > -1e-8f ? 0.f : a / b; }
template< size_t N >
float cosine_similarity( std::array<float, N> a, std::array<float, N> b )
{
const float&& a2 = std::move( std::inner_product( a.begin(), a.end(), a.begin(), 0.f ) );
const float&& b2 = std::move( std::inner_product( b.begin(), b.end(), b.begin(), 0.f ) );
const float&& dot_product = std::move( std::inner_product( a.begin(), a.end(), b.begin(), 0.f ) );
return safe_divide( dot_product, ( std::sqrt(a2) * std::sqrt(b2) ) );
}
int main(){
std::array<float, 5> a{1,1,1,1,1}, b{-1,1,-1,1,-1};
std::cout<<cosine_similarity(a,b);
}
On x86-64 Clang 12.0.1 (and other versions), it compiles and gives the right answer.
However on every version of GCC that I've tested it compiles, but gives the wrong answer (or no answer).
It raises a few questions:
- Is my use of
std::moveeven valid? - Why does only Clang seem to work with this and no other compiler?
- What does the standard say?
Here's a link to the experiment: https://godbolt.org/z/KWbMYorrc