复杂的constexpr替代品

时间:2017-08-18 02:32:08

标签: templates visual-c++ c++14

考虑

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

因为一个人不能写

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

作为另一种写作

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

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

现在考虑

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;

对于某些人来说

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

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

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

打印正确的值(即(0,-2))here但是当MSVC ++编译时,相同的代码打印(0,0)

我有两个问题

1)为什么在MSVC ++上如此,是否有已知的解决方法?

2)struct A是否比struct B有更好的选择,而{{1}}并不完全相同......

1 个答案:

答案 0 :(得分:1)

看起来像编译器错误,除非我遗漏了什么。这不是一个真正的答案,只是分享我发现的东西。这是我可以演绎出来的最小例子:

#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;
}

令人惊讶的是,除非我将func指定为constexpr或指定-stdlib=libc++(至少在coliru上)

我想你可以跳过上面的一个问题来解决你的问题。如果您将ComplexEspression标记为static constexpr Complex value = ComplexExpresion(D::value);,则可以constexpr