admin管理员组文章数量:1435228
I have a template struct Distance
that uses constexpr unsigned char mm2cm = 10
Since Distance
is a template class, I must define mm2cm
and Distance
in a header file.
This header file is included by cpp files.
I want mm2cm
to only be visible in this header file and not in the cpp files that include this header, ie:
Distance.hpp
constexpr unsigned char mm2cm = 10;
template <int offset>
struct Distance{
int mm;
int convToCm() const { return offset + mm2cm * mm; }
};
Main.cpp
#include "Distance.hpp"
#include <iostream>
int main(){
//I do not want to be able to use mm2mm outside Distance.hpp, as follows
std::cout << (int)mm2cm << std::endl;
}
One way I could solve this is using #define mm2cm 10
and #undef mm2cm
at the beggining and end of the header file (instead of constexpr unsigned char mm2cm = 10
.
However, a lot of people discourage the use of macros for reasons. This post lists some reasons why), and this website states that:
In general, the const keyword is preferred for defining constants and should be used instead of #define.
Another way I could solve this is by making mm2cmm
a private static member of Distance
.
However, in the actual, larger problem I am trying to solve, I have multiple variables that I only want to be visible in this header file, and making all of them private static members will make my class look ugly (in other words, there must be a better way than this solution).
I would be most grateful if someone could provide me the most optimal way to ensure mm2cm
is only visible to Distance
or only visible within this header file.
A prior edition of this post used a type template parameter. This has been changed to a non-type template parameter since the actual problem I am trying to solve uses a non-type template parameter.
I have a template struct Distance
that uses constexpr unsigned char mm2cm = 10
Since Distance
is a template class, I must define mm2cm
and Distance
in a header file.
This header file is included by cpp files.
I want mm2cm
to only be visible in this header file and not in the cpp files that include this header, ie:
Distance.hpp
constexpr unsigned char mm2cm = 10;
template <int offset>
struct Distance{
int mm;
int convToCm() const { return offset + mm2cm * mm; }
};
Main.cpp
#include "Distance.hpp"
#include <iostream>
int main(){
//I do not want to be able to use mm2mm outside Distance.hpp, as follows
std::cout << (int)mm2cm << std::endl;
}
One way I could solve this is using #define mm2cm 10
and #undef mm2cm
at the beggining and end of the header file (instead of constexpr unsigned char mm2cm = 10
.
However, a lot of people discourage the use of macros for reasons. This post lists some reasons why), and this website states that:
In general, the const keyword is preferred for defining constants and should be used instead of #define.
Another way I could solve this is by making mm2cmm
a private static member of Distance
.
However, in the actual, larger problem I am trying to solve, I have multiple variables that I only want to be visible in this header file, and making all of them private static members will make my class look ugly (in other words, there must be a better way than this solution).
I would be most grateful if someone could provide me the most optimal way to ensure mm2cm
is only visible to Distance
or only visible within this header file.
A prior edition of this post used a type template parameter. This has been changed to a non-type template parameter since the actual problem I am trying to solve uses a non-type template parameter.
Share Improve this question edited Nov 17, 2024 at 1:45 Remy Lebeau 602k36 gold badges508 silver badges853 bronze badges asked Nov 16, 2024 at 21:52 timmy geetimmy gee 6431 silver badge12 bronze badges 13 | Show 8 more comments2 Answers
Reset to default 0Reviewing your requirements, this is the best I could come up with...
template <int offset>
struct Distance {
private:
enum Constants : unsigned char {
mm2cm = 10,
};
public:
int mm;
int convToCm() const { return offset + mm2cm * mm; }
};
It hides the value in an enum, and can be used with other constants.
convToCm()
looks like it is the wrong way (looks like it converts cm to mm.)
If mm2cm was an object or function, then it would inhibit the compiler's ability to optimize. We could do a base class implementation, but that would still have the "ugly" multiple private / static members.
The use of integer offset as a template is awkward for the compiler.
Distance<10> value;
Distance<12> value2;
Requires the compiler to generate
int Distance<10>::convToCm() const;
int Distance<12>::convToCm() const;
Both of which have identical code except for the template parameter 10/12. This would be more problematic if the objects were in a container, where std::vector< Distance<10> >
requires different code to std::vector< Distance<12> >
Try this:
Distance.hpp
#ifndef DISTANCE_HPP
#define DISTANCE_HPP
template <typename UnitType>
struct Distance {
UnitType mm;
UnitType convToCm() const; // Declaration only
};
#endif // DISTANCE_HPP
Distance.cpp
#include "Distance.hpp"
namespace { // Anonymous namespace hides this constant
constexpr unsigned char mm2cm = 10;
}
template <typename UnitType>
UnitType Distance<UnitType>::convToCm() const {
return mm * mm2cm;
}
// Explicit instantiations (if needed)
template struct Distance<int>;
template struct Distance<float>;
Main.cpp
#include "Distance.hpp"
#include <iostream>
int main() {
Distance<int> dist{100};
std::cout << dist.convToCm() << std::endl; // Outputs 1000
// The following line will fail to compile, as mm2cm is not visible:
// std::cout << (int)mm2cm << std::endl;
return 0;
}
本文标签: cHow to make a variable hidden in a header fileStack Overflow
版权声明:本文标题:c++ - How to make a variable hidden in a header file - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745642410a2667937.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
mm2cm
? Whenever you feel the need to do a C-style explicit conversion like that, you should take it as a sign that you're probably are doing something wrong. – Some programmer dude Commented Nov 16, 2024 at 22:15detail
, that universally means private among C++ developers, as in, don't access it as i will change it in any day, it is an implementation detail – Ahmed AEK Commented Nov 16, 2024 at 22:15private
and they arestatic
in nature, so making themprivate
andstatic constexpr
would be my first choice. – Ted Lyngmo Commented Nov 17, 2024 at 0:04int convToCm() const { constexpr int mm2cm = 10; return offset + mm2cm * mm; }
– Ted Lyngmo Commented Nov 17, 2024 at 0:15