Suppose in header file, we have something like this.
namespace impl_{
int do_something_(){
return 1;
}
}
int do_something(){
using namespace impl_;
return do_something_();
}
impl_::do_something_() is well hidden, but it is "included" in the output object file.
If we want the function not to be included, we need to do it inline or static... or to add one more namespace???
namespace impl_{
namespace {
int do_something_(){
return 1;
}
}
}
... actually, this works too...
namespace {
namespace impl_{
int do_something_(){
return 1;
}
}
}
Note this imply to both header and implementation files, but for header files is bigger problem.
I am very confuse - what would be the best way / best practice to do this kind of "hiding implementation code" inside the header files?
Related
I want to copy protobuf msg "SmConfig" to an shared_ptr like below:
SignalMachine::SignalMachine(SmConfig* sm_config) {
sm_config_ = std::make_shared<SmConfig>();
sm_config_.CopyFrom(*sm_config);
}
class SignalMachine {
private:
std::shared_ptr<SmConfig> sm_config_;
}
Because I need to keep SmConfig(protobuf) in "class SignalMachine", I used the above method, is it reasonable? in fact, I did not find the corresponding description in the official document.
You can use copy constructor:
SignalMachine::SignalMachine(SmConfig* sm_config) {
if (sm_config != nullptr)
sm_config_ = std::make_shared<SmConfig>(*sm_config);
// else error handling
}
I am trying to understand an error I see when attempting to implement the Visitor pattern for validation purpose. When i execute cmake ../ from the build directory i am getting the following error:
validator/src/Id.cpp:30:38: error: no viable conversion from 'shared_ptr<src::IdInterface>' to 'shared_ptr<IdInterface>'
bool isValid = validator->isValid( castedObj );
/home/tito/Projects/validator/src/IdValidatorInterface.h:24:50: note: passing argument to parameter 'entity' here
virtual bool isValid( shared_ptr<IdInterface> entity ) = 0;
I have been able to replicate the error with simple 3 classes For the sake of the example i have put them in the same namespace.
Those classes are "Id" class this is the element i would like to validate. The Id inherits from BasePrimitive. The sole purpose of BasePrimitive class is to be able to get a share pointer validating entity since the BasePrimitive class inherits from
"enable_shared_from_this". i.e. the code below
#include "Id.h"
#include "IdInterface.h"
#include "IdValidatorInterface.h"
#include <iostream>
using namespace std;
namespace src
{
const string Id::name = "ID";
Id::Id()
{
}
Id::~Id()
{
}
bool Id::validate(shared_ptr<IdValidatorInterface> validator)
{
shared_ptr<Id> thisObj = shared_from_this();
shared_ptr<IdInterface> castedObj = static_pointer_cast<IdInterface>(thisObj);
bool isValid = validator->isValid( castedObj );
if (!isValid)
{
vector<string> vectorOfErrors = validator->validate(castedObj );
std::cout << " the Id has NOT been validated" << std::endl;
} else
{
std::cout << " the Id has been validated" << std::endl;
}
return isValid;
}
string Id::getName() const {
return Id::name;
}
}
the part where the code is broken is this one: Here i get a share_ptr from this class and then do a static pointer case. This works well but when i try to pass it to the isValid method then it breaks.
shared_ptr<Id> thisObj = shared_from_this();
shared_ptr<IdInterface> castedObj = static_pointer_cast<IdInterface>(thisObj);
bool isValid = validator->isValid( castedObj );
and the BasePrimitive class
namespace src {
class BasePrimitive: public enable_shared_from_this<BasePrimitive> {
public:
~BasePrimitive();
BasePrimitive();
};
}
Then i have my validator class i.e. IdValidator
#include "IdValidator.h"
#include "Id.h"
#include "IdInterface.h"
using namespace std;
namespace src
{
using Id = src::Id;
IdValidator::IdValidator()
{
}
bool IdValidator::isValid(shared_ptr<IdInterface> entity)
{
vector<string> listOfErros = validate(entity);
if(listOfErros.empty() ){
return false;
}else{
return true;
}
}
vector<string> IdValidator::validate(shared_ptr<IdInterface> entity)
{
vector<string> stringList = vector<string>();
// do some validation of the name
string name = entity->getName()
if (name == "BadName")
{
string error = "Error. id name is bad";
stringList.push_back(error);
return stringList;
}
return stringList;
}
}
And i do have 3 other interfaces i.e. BaseElementValidatorInterface, IdValidatableInterface, IdValidatorInterface which are there simply for explicit in order to state that those a pure virtual functions.
in the last interface i.e. IdValidatorInterface i am using a forward declare to the IdInterface in order to avoid cyclic includes.
i.e.
class IdInterface;
The first probelm:
"no viable conversion from 'shared_ptr' to 'shared_ptr'"
the only difference here i see is the full qualified namespace. I would like to understand the nature i.e. the origin of this error. Is this something related to the compiled definitions I pass to clang i.e.
add_definitions(" -pedantic -pedantic-errors -W ")
add_definitions(" -Wall -Wextra -Werror -Wshadow -Wnon-virtual-dtor ")
add_definitions(" -v ")
or something else.
I have found multiple articles in stackoverflow about this but all of those were mainly about different types i.e. somethig like bools and string.
like this one
no viable conversion from 'int' to 'Time'
No viable conversion from 'bool' to 'std::string'
I do understand the articles mentioned above, but in my case the compiler is seeing the same type except the namespace is different i.e.'shared_ptr' to 'shared_ptr' how to i tell the compiler that those are the same objects? Why is the compiler seeing different namespaces when this is the same class i.e. "IdInterface". In some of the articles above it has been mentioned that this error can be seen if the class in not defined , but for this reason i use explicetelly the fotrward declaration.
I have put those whole 3 classes and the 3 interfaces on github to show the complete picture. https://github.com/courteous/visitor/tree/master/src
Any help is highly appreciated
I got 2 classes that represent Player and I want to keep in one of them pointer to another one.
So inside my view::Player I create pointer to logic::Player
namespace view {
class Player {
std::shared_ptr<logic::Player> m_player;
//logic::Player* m_player;
public:
void create(logic::Player& player) {
m_player = std::make_shared<logic::Player>(player);
//m_player = &player;
}
};
}
view::Player is created in view::GameState and simply initialised like this
m_playerOneView.create(m_game.getActivePlayer());
m_game is logic::Game object
logic::Game has std::vector<logic::Player>, and public method that returns active one
logic::Player& logic::Game::getActivePlayer() {
return m_players[m_activePlayer];
}
And finnaly
namespace logic {
class Player {
std::string m_name;
int position;
};
}
Now I need original object of logic::Player pointed by std::shared_ptr in my view::Player class. I could simply do that by changing that to raw pointer and it works then (2 commented lines do what I want to achieve basicly). But when I try to do this on std::shared_ptr, I seem to work on copy of logic::Player, because when I update his position for example, it changes everywhere in the game but not in view::Player. How to do that using std::shared_ptr then?
Is there a way to use enum default parameters in Haxe? I get this error:
Parameter default value should be constant
enum AnEnum {
A;
B;
C;
}
class Test {
static function main() {
Test.enumNotWorking();
}
static function enumNotWorking(e:AnEnum = AnEnum.A){}
}
Try Haxe link.
Update: this feature has been added in Haxe 4. The code example from the question now compiles as-is with a regular enum.
Previously, this was only possible if you're willing to use enum abstracts (enums at compile time, but a different type at runtime):
#:enum
abstract AnEnum(Int)
{
var A = 1;
var B = 2;
var C = 3;
}
class Test3
{
static function main()
{
nowItWorks();
}
static function nowItWorks(param = AnEnum.A)
{
trace(param);
}
}
There's nothing special about the values I chose, and you could choose another type (string, or a more complex type) if it better suits your use case. You can treat these just like regular enums (for switch statements, etc.) but note that when you trace it at runtime, you'll get "1", not "A".
More information: http://haxe.org/manual/types-abstract-enum.html
Sadly enums can't be used as default values, because in Haxe enums aren't always constant.
This piece of trivia was on the old website but apparently hasn't made it into the new manual yet:
http://old.haxe.org/ref/enums#using-enums-as-default-value-for-parameters
The workaround is to check for a null value at the start of your function:
static function enumNotWorking(?e:AnEnum){
if (e==null) e=AnEnum.A;
}
Alternatively, an Enum Abstract might work for your case.
I have this function that's supposed to generate different derived objs and return as a unique_ptr<base>:
class base {}; // contains pure functions.
class derived1 {}; // reifies that pure iface.
class derived2 {}; // reifies that pure iface.
unique_ptr<base> factory::load(int param)
{
switch (param)
{
case PARAM_MAIN:
return new derived1();
// return std::move(new derived1());
case PARAM_2:
return new derived2();
case ...:
return new derived...();
}
}
there's no way I can get this thing going, even using the std::move. (Also used dynamic_cast, but maybe did it wrong).
This is the error I get: (gcc (GCC) 4.8.1 20130725 (prerelease) on ArchLinux)
could not convert '(std::shared_ptr<base::model>((*(const std::shared_ptr<base::model>*)(& associatedModel))), (operator new(48ul), (<statement>, ((derived1*)<anonymous>))))' from 'derived1*' to 'std::unique_ptr<base>'
associatedModel));
I hope I've been clear about what I wanna do.
How do I do it? Thanks.
You can either do unique_ptr<derived1>(new derived1()); or even better (with C++14) use std::make_unique.
using namespace std;
class base {}; // contains pure functions.
class derived1 {}; // reifies that pure iface.
class derived2 {}; // reifies that pure iface.
unique_ptr<base> factory::load(int param) {
switch (param) {
case PARAM_MAIN: return make_unique<derived1>();
case PARAM_2: return make_unique<derived2>();
case ...: return make_unique<derived...>();
}
}
I solved it this way:
return unique_ptr<base>(dynamic_cast<base*>(std::move(
new derived1()
)));
So the point is that it has to be upcasted to base while its still raw, and only then be wrapped in the unique_ptr.
I appreciate simpler answers anyway. Especially those reasoning based on the internals of unique_ptr and the implementation.