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
Is there a way to convert a string to an enum?
enum eCommand{fred, joe, harry}
eCommand theCommand= cast(eCommand, 'joe');??
I think I just have to search for the enum (eg loop).
cheers
Steve
I got annoyed with the state of enums and built a library to handle this:
https://pub.dev/packages/enum_to_string
Basic usage:
import 'package:enum_to_string:enum_to_string.dart';
enum TestEnum { testValue1 };
main(){
final result = EnumToString.fromString(TestEnum.values, "testValue1");
// TestEnum.testValue1
}
Still more verbose than I would like, but gets the job done.
I have came up with a solution inspired from https://pub.dev/packages/enum_to_string that can be used as a simple extension on List
extension EnumTransform on List {
String string<T>(T value) {
if (value == null || (isEmpty)) return null;
var occurence = singleWhere(
(enumItem) => enumItem.toString() == value.toString(),
orElse: () => null);
if (occurence == null) return null;
return occurence.toString().split('.').last;
}
T enumFromString<T>(String value) {
return firstWhere((type) => type.toString().split('.').last == value,
orElse: () => null);
}
}
Usage
enum enum Color {
red,
green,
blue,
}
var colorEnum = Color.values.enumFromString('red');
var colorString: Color.values.string(Color.red)
Dart 2.6 introduces methods on enum types. It's much better to call a getter on the Topic or String itself to get the corresponding conversion via a named extension. I prefer this technique because I don't need to import a new package, saving memory and solving the problem with OOP.
I also get a compiler warning when I update the enum with more cases when I don't use default, since I am not handling the switch exhaustively.
Here's an example of that:
enum Topic { none, computing, general }
extension TopicString on String {
Topic get topic {
switch (this) {
case 'computing':
return Topic.computing;
case 'general':
return Topic.general;
case 'none':
return Topic.none;
}
}
}
extension TopicExtension on Topic {
String get string {
switch (this) {
case Topic.computing:
return 'computing';
case Topic.general:
return 'general';
case Topic.none:
return 'none';
}
}
}
This is really easy to use and understand, since I don't create any extra classes for conversion:
var topic = Topic.none;
final string = topic.string;
topic = string.topic;
(-:
As of Dart 2.15, you can use the name property and the byName() method:
enum eCommand { fred, joe, harry }
eCommand comm = eCommand.fred;
assert(comm.name == "fred");
assert(eCommand.values.byName("fred") == comm);
Just be aware that the byName method throws an ArgumentError if the string is not recognized as a valid member in the enumeration.
For the Dart enum this is a bit cumbersome.
See Enum from String for a solution.
If you need more than the most basic features of an enum it's usually better to use old-style enums - a class with const members.
See How can I build an enum with Dart? for old-style enums
This is the fastest way I found to do this :
enum Vegetable { EGGPLANT, CARROT, TOMATO }
Vegetable _getVegetableEnum(dynamic myVegetableObject) {
return Vegetable.values.firstWhere((e) => describeEnum(e) == myVegetableObject);
}
i had the same problem, a small enum and a string, so i did this
dynamic _enum_value = EnumFromString(MyEnum.values, string_to_enum);
dynamic EnumFromString(List values, String comp){
dynamic enumValue = null;
values.forEach((item) {
if(item.toString() == comp){
enumValue = item;
}
});
return enumValue;
}
i know this is not the best solution, but it works.
Static extension methods would make this nice (currently unimplemented).
Then you could have something like this:
extension Value on Keyword {
/// Returns the valid string representation of a [Keyword].
String value() => toString().replaceFirst(r'Keyword.$', '');
/// Returns a [Keyword] for a valid string representation, such as "if" or "class".
static Keyword toEnum(String asString) =>
Keyword.values.firstWhere((kw) => kw.value() == asString);
}
FOUND ANS
Check this article. Very well explained: Link
extension EnumParser on String {
T toEnum<T>(List<T> values) {
return values.firstWhere(
(e) => e.toString().toLowerCase().split(".").last ==
'$this'.toLowerCase(),
orElse: () => null,
),
}
}
The cleanest way is to use built-in functionality:
enum EmailStatus {
accepted,
rejected,
delivered,
failed,
}
EmailStatus.values.byName('failed') == EmailStatus.failed;
=> true
If not, is there anything like this on the horizon?
This is the one feature of JavaScript, Ruby, and Perl that I can't live without. I know you can fake it with a hash member, but I want to be able to create (arbitrary) "first class" members from a parser.
Currently there's nothing that can set a field that doesn't yet exist. The mirror API can be used to set fields that already exist, and may eventually be extended to support defining new fields dynamically.
You can also use the "noSuchMethod" method on a class to intercept setter / getter, and store the received value in a map.
For example (I can't remember the syntax exactly...):
class Foo {
var _dynamicProperties = new Map<String,Object>();
noSuchMethod(String function_name, List args) {
if (args.length == 0 && function_name.startsWith("get:")) {
// Synthetic getter
var property = function_name.replaceFirst("get:", "");
if (_dynamicProperties.containsKey(property)) {
return _dynamicProperties[property];
}
}
else if (args.length == 1 && function_name.startsWith("set:")) {
// Synthetic setter
var property = function_name.replaceFirst("set:", "");
// If the property doesn't exist, it will only be added
_dynamicProperties[property] = args[0];
return _dynamicProperties[property];
}
super.noSuchMethod(function_name, args)
}
}
And then you can use this in your code as follows:
var foo = new Foo();
foo.bar = "Hello, World!";
print(foo.bar);
Of course, this can lead to typos that will not be checked by the type checker, e.g.:
foo.bar = "Hello";
foo.baz = "Hello, World!"; // Typo, meant to update foo.bar.
There are ways you have type-checker validation by using redirecting factory constructors and an implied interface, but then it starts to get complicated.
Side note: This is what JsonObject uses to convert a JSON map to a class type syntax.
I'm writing an Add-in for VS 2010. Can't find answer for a question - How can i get the Access property of a CodeElement if it has that one.
I was trying reflection, but no results.
Ex. CodeElement is a class method
public void GetAccess (CodeElement codeElement)
{
object code = codeElement;
Type t = code.GetType();
t.GetProperty("Access") = vsCMAccess.vsCMAccessPublic;
}
But it doesnt work..
Help, please!
Access is only available on some types of CodeElements, so you'll need to check for the type of CodeElement you have, cast to the specific type and then retrieve the property.
Example:
if (codeElement.Kind == vsCMElementFunction)
{
return ((CodeFunction)codeElement).Access;
}
else if (codeElement.Kind == vsCMElementProperty)
{
return ((CodeProperty)codeElement).Access;
}
I have something like this:
enum EFood{
eMeat,
eFruit
};
class Food{
};
class Meat: public Food{
void someMeatFunction();
};
class Fruit: public Food{
void someFruitFunction();
};
class FoodFactory{
vector<Food*> allTheFood;
Food* createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
if(food)
allTheFood.push_back(food);
return food;
}
};
int foo(){
Fruit* fruit = dynamic_cast<Fruit*>(myFoodFactory->createFood(eFruit));
if(fruit)
fruit->someFruitFunction();
}
now I want to change my application to use boost shared_ptr and weak_ptr such that i can delete my food instance in a single place. it would look like this:
class FoodFactory{
vector<shared_ptr<Food> > allTheFood;
weak_ptr<Food> createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
shared_ptr<Food> ptr(food);
allTheFood.push_back(ptr);
return weak_ptr<Food>(ptr);
}
};
int foo(){
weak_ptr<Fruit> fruit = dynamic_cast<weak_ptr<Fruit> >(myFoodFactory->createFood(eFruit));
if(shared_ptr<Fruit> fruitPtr = fruit.lock())
fruitPtr->someFruitFunction();
}
but the problem is that the dynamic_cast doesn't seem to work with weak_ptr
how do I get a weak_ptr<Fruit> out of a weak_ptr<Food> if i know that the object it points to is of derived type?
Direct casting from weak_ptr<A> to weak_ptr<B> will surely don't work, I think you have to convert it to a shared_ptr and then use the casting functionality of shared_ptr:
weak_ptr<Food> food = myFoodFactory->createFood(eFruit)
weak_ptr<Fruit> fruit = weak_ptr<Fruit>(dynamic_pointer_cast<Fruit>(food.lock());
You cannot use dynamic_cast with shared_ptr because it would require to change the template of the object. What in fact you want to do is a dynamic_cast on the internal pointer. To do this you could do a dynamic_cast on the pointer returned by get but that would not be so clean because the reference would not be shared(irrelevant in your case since you're using weak_ptr but relevant when using shared_ptr) and creating a share_ptr on this would be undefined resulting on a double delete.
Use dynamic_pointer_cast to do this but the two types still need to be related. In other words dynamic_cast<T*>(r.get()) needs to be well formed.
you can use BOOST_DISABLE_THREADS to improve performance if you're not bound to multithreading, see https://stackoverflow.com/a/8966130/1067933