Search code examples
c++templatesexternbitset

How to use a C++ extern constant variable for a template argument in a different file


I have the following 5 files: global_vars.h, global_vars.cpp content.h content.cpp main.cpp.

global_vars.h

#ifndef global_vars_h
#define global_vars_h

namespace Constants{

    extern const unsigned int b;

}

#endif

global_vars.cpp

#include "global_vars.h"

namespace Constants{

    extern const unsigned int b(5);


}

content.h

#ifndef CONTENT_H_
#define CONTENT_H_

#include "global_vars.h"
#include <bitset>

struct a{

    std::bitset<Constants::b> s;
    int a=10;

};

#endif

content.cpp

#include "content.h"

a xVar;

main.cpp

#include "content.h"
int main(){
   return 0;
}

I get the following errors:

In file included from content.cpp:1:0:
content.h:11:31: error: the value of ‘Constants::b’ is not usable in a constant expression

In file included from content.h:4:0,
from content.cpp:1:
global_vars.h:6:28: note: ‘Constants::b’ was not initialized with a constant expression
extern const unsigned int b;

I have to use Constants::b in files other than content.cpp/.h (for other bitsets) as well so how can I go around doing this? Appreciate the help.

thanks


Solution

  • What you ask is not possible.

    In C++, templates are resolved entirely by the compiler, the linker only gets to see fully instantiated bodies of template classes and functions. The compiler only gets to see code that is in a given compilation unit.

    Therefore, even if an int is extern const and assigned a value in some compilation unit (making it valid at run-time), it cannot possibly be used as a template parameter in any other compilation unit. There would be no way for the compiler to know the value of that int at the time that it is resolving which template instantiations refer to the same types.

    The closest you can get most likely, is that you could a pointer to that int as a template parameter, and then if you have e.g. a function using that template parameter which is run at run-time, it could dereference the pointer to get the constant value. If you have link-time optimizations enabled it might even inline it, I'm not sure.