Michael Medvinsky
Michael Medvinsky

Reputation: 326

complex constexpr alternatives

Consider

typedef std::complex<double> Complex;
Complex ComplexExpresion(int a) {return Complex(0,-a);}

Since one cannot write

template<typename D>    
struct A
{
  static constexpr Complex value = ComplexExpresion(D::value);
};

as an alternative one writes

template<typename D> 
struct B
{
  static const Complex value; 
};

template<typename D> 
const Complex B<D>::value = ComplexExpresion(D::value);

Consider now

template<typename D, int N> 
struct C;

template<typename D> 
struct C<D,1>
{
  static const Complex value; 
};

template<typename D> 
const Complex C<D,1>::value = B<D>::value;

For some reasone

struct Data
{
    static auto constexpr value =2;
};

int main()
{
        using C = C<Data,1>;

        std::cout << C::value;
}

prints the correct value(which is (0,-2) ) here but the same code prints (0,0) when complied by MSVC++

I have 2 questions

1) why it is so on MSVC++ and is there known workaround?

2) is there better alternative for struct A than struct B which is not exactly the same thing...

Upvotes: 0

Views: 191

Answers (1)

kmdreko
kmdreko

Reputation: 60493

Looks like a compiler bug unless I'm missing something. This isn't really an answer, just sharing what I found. This is the smallest example I could deduce that exhibits the issue:

#include <iostream>

// using function is important
int func() { return 1; }

// template is imporant
template<class D>
struct B
{
  static const int value;
};

// defined outside block is important
template<class D>
const int B<D>::value = func();

// going through C is important
struct C
{
  static const int value;
};

const int C::value = B<int>::value;

int main()
{
  // should print 1 but prints 0
  std::cout << C::value << std::endl;
}

surprisingly this also trips up clang unless I specify func as constexpr or specify -stdlib=libc++ (at least on coliru)

I guess you can fix your issue by skipping one of the bits above. You can do static constexpr Complex value = ComplexExpresion(D::value); if you mark ComplexEspression as constexpr.

Upvotes: 1

Related Questions