Reputation: 326
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
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