1

I have a Vec struct that represents a 3D vector, and I want to make it's static member Zero constexpr.

struct Vec
{
    double X;
    double Y;
    double Z;

    static const Vec Zero; // defined in it's own .cpp file

    // ... some functions and operators
};

I tried the following approach, but this code fails to compile with incomplete type is not allowed.

struct Vec
{
    double X;
    double Y;
    double Z;

    static constexpr Vec Zero{ 0.0, 0.0, 0.0 };
};

Then I tried to move the definition out of the struct. This compiles, but fails in linking phase, with duplicate symbol Vec::Zero error. (Vec is in the .h file that is included by many .cpp files)

struct Vec
{
    double X;
    double Y;
    double Z;

    static const Vec Zero;
};
constexpr Vec Vec::Zero{ 0.0, 0.0, 0.0 }; // this definition is in .h file, not in .cpp

What is the proper way to make Vec::Zero constexpr? Is it possible at all?

EDIT: As pointed out by @Artyer, since C++17 inline can be used to solve the problem. The following code works:

struct Vec
{
    double X;
    double Y;
    double Z;

    static const Vec Zero;
};
inline constexpr Vec Vec::Zero{ 0.0, 0.0, 0.0 }; // this definition is in .h file, not in .cpp
Eugene
  • 91
  • 7
  • 1
    Are you using C++17? If so, you just need to change your last example to `inline constexpr Vec Vec::Zero{ 0.0, 0.0, 0.0 };` – Artyer Mar 23 '23 at 12:16
  • What is the problem with your last piece of code? If any? Please add info such as language version. – Andrés Alcarraz Mar 23 '23 at 12:25
  • @AndrésAlcarraz *This compiles, but fails in linking phase, with duplicate symbol Vec::Zero error. (Vec is in the .h file that is included by many .cpp files)* – NathanOliver Mar 23 '23 at 12:25
  • Can I suggest you to add that to the question, so it states the problem is more clear? – Andrés Alcarraz Mar 23 '23 at 12:27
  • Maybe you also forgot include guards or just `#pragma once` at the start of the file? – Peter Krebs Mar 23 '23 at 12:36
  • @AndrésAlcarraz That is in the Q, I quoted it. (note that I am not the OP) – NathanOliver Mar 23 '23 at 12:41
  • @PeterKrebs That is not the issue. A non-inline out of line constexpr definition is not `inline`, so if you include it in multiple different TU's you will get a multiple definition error as each TU has a definition. – NathanOliver Mar 23 '23 at 12:43
  • @Artyer, yes, I'm using C++17. `inline` seems to solve the issue, thanks. Never thought of using it in this context. – Eugene Mar 23 '23 at 12:44
  • @NathanOliver, sorry I swear to you that I read that part, more than once, and somehow I didn't see it. – Andrés Alcarraz Mar 23 '23 at 18:48

0 Answers0