Max Ehrlich - 1 year ago 97

C++ Question

I know it's a pretty general title, but I have some code and it strikes me as weird that it cant compile.

Here is a demo of the issue. If you change

`scalar_t`

`double`

`float`

`double`

`1.0`

`int`

`1`

Full code sample:

`#include <valarray>`

#include <numeric>

#include <iterator>

#include <iostream>

template<typename T>

T sigmoid(const T &in)

{

return 1.f / (1.f + std::exp(-in));

}

template<typename T>

T logit(const T &in)

{

return std::log(in / (1.f - in));

}

using scalar_t = double;

int main(int argc, char **argv)

{

std::valarray<scalar_t> f = { 0.1f, 0.3f, 0.5f, 0.9f };

scalar_t alpha = 0.5f;

scalar_t beta = -1.f;

auto lC = logit(f);

std::valarray<scalar_t> skC = alpha * lC + beta;

auto sC = sigmoid(skC);

std::copy(std::begin(sC), std::end(sC), std::ostream_iterator<scalar_t>(std::cout, " "));

std::cout << std::endl;

scalar_t num = 0.7f;

auto lS = logit(num);

auto sS = sigmoid(alpha * lS + beta);

std::cout << sS << std::endl;

return 0;

}

This spawned a pretty interesting discussion about how to use constants in these type agnostic templates. Surprisingly there seems to be an answer. Examining the

`sigmoid`

`float`

`valarray<double>`

`std::exp(-in)`

`valarray<double>`

`float`

`double`

`logit`

`valarray<double>`

`float`

Here is the update code sample

and the new

`logit`

`template<typename T>`

T logit(const T &in)

{

return std::log(in / (1.f - (+in)));

}

Note the unary + operator

`(+in)`

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

The `operator -`

you are using is defined as

```
template <class T> std::valarray<T> operator- (const T& val, const std::valarray<T>& rhs);
```

This meas that it expects `val`

to be the same type as the elements in the `valarray`

. Since you are using a `float`

when template argument deduction happens it sees that `val`

is a `float`

but `rhs`

has a element type of `double`

. since these types do not match the deduction fails and you get a compiler error. Remember no conversions happen during template argument deduction.