3

I tried to compile the following code, but failed.

#include <iostream>
#include <vector>

struct Foo {
  static constexpr int A = 10;
  static constexpr int B = 10;

  std::vector<int> dat;

  Foo() : dat(A, B) {}
};

int main() {
  Foo foo;
}

Error message:

$ g++ a.cpp -std=c++11
/tmp/ccSaJJrd.o: In function `Foo::Foo()':
a.cpp:(.text._ZN3FooC2Ev[_ZN3FooC5Ev]+0x25): undefined reference to `Foo::B'
collect2: error: ld returned 1 exit status

Curiously, the following code can be compiled:

#include <iostream>
#include <vector>

struct Foo {
  static constexpr int A = 10;

  std::vector<int> dat;

  Foo() : dat(A, 10) {}
};

int main() {
  Foo foo;
}

Why cannot the second argument receive a constexpr value?

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
adapchi
  • 31
  • 1
  • 4
    Because the [constructor of `std::vector`](http://en.cppreference.com/w/cpp/container/vector/vector) takes the size argument by value, and the default value by const-reference. As to why you need a definition for `B` in the first case, you can check https://stackoverflow.com/questions/29397864/why-does-constexpr-static-member-of-type-class-require-a-definition. – Holt Sep 21 '17 at 13:14
  • 2
    The constructor selected by `dat(A, B)` odr-uses the second argument (because it's bound to a reference). The first argument is not odr-used (because it's passed by value). – Kerrek SB Sep 21 '17 at 13:16

0 Answers0