#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>

template <typename Container, typename T = typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type>
T variance(Container && c)
{
    auto b = std::begin(c), e = std::end(c);
    auto size = std::distance(b, e);
    auto sum = std::accumulate(b, e, T());
    auto mean = sum / size;
    T accum = T();
    for (const auto d : c)
        accum += (d - mean) * (d - mean);
    return std::sqrt(accum / (size - 1));
}

int main() {
	// Works with vectors
	std::vector<double> v = { 1.0, 2.5, 3.7 };
	std::cout << variance(v) << std::endl;
	
	// Works with raw arrays
	double a[] = { 1.0, 2.5, 3.7 };
	std::cout << variance(a) << std::endl;
	
	// Ok this is ugly... But I want to enforce T=double in the function template.
	int b[] = { 1, 2, 4 };
	std::cout << variance<int (&)[3],double>(b) << std::endl;
	
	return 0;
}