Undefined reference error for constexpr static member

Consider this code:

#include <vector>

struct A {
  static constexpr int kDefaultValue = -1;
  std::vector<int> v;
  A(int n): v(n, A::kDefaultValue) {}
};

int main() {
  A(10);
  return 0;
}

Unable to bind (llvm clang, gcc 4.9, like on OS X):

Undefined symbols for architecture x86_64:
  "A::kDefaultValue", referenced from:
      A::(int) in main.cpp.o
ld: symbol(s) not found for architecture x86_64

The question is, what's wrong with that? It can be fixed with static_cast-ing A::kDefaultValueup int. Or by moving kDefaultValuefrom A. Both cases seem ugly. Is this another way to make a link?

+4
source share
2 answers

This behavior annoys me again and again. The cause of the problem is that your

A(int n): v(n, A::kDefaultValue) {}

The odr-uses memberstatic constexpr, since the constructorvaccepts a permalink of the second argument. To use Odr, a definition is required somewhere, i.e.

const int A::kDefaultValue;

( main()). ++ 17, ( ) .

(, ), , -

A(int n): v(n, int(A::kDefaultValue)) {}

v ( , ).

+3

++ 17. ++ 17 constexpr static data member , - ; ++ 17 .

constexpr, . ( , ) , . ( ++ 17)

, ++ 17, .

LIVE demo gcc7

+5

Source: https://habr.com/ru/post/1661266/


All Articles