I am trying to implement a rate-limiting handler with Kemal.
I have a class, RateLimiter, that inherits the class Kemal::Handler. On compile I get the error:
Error in src/rate_limiter.cr:5: superclass mismatch for class RateLimiter (Kemal::Handler for Reference)
I'm new to Crystal and that means nothing to me. What am I doing wrong?
This indicates that RateLimiter was defined previously somewhere, without any explicit superclass specification:
class Base; end
class Foo; end
class Foo < Base; end
That gives
Error in line 3: superclass mismatch for class Foo (Base for Reference)
https://carc.in/#/r/3r2l
Search through your project and dependencies for class RateLimiter giving conflicting definitions of that type.
Related
I have a pure virtual template base class, in which I define a method get_value which takes an enumeration and returns an int. The complication is that each derived class will use a different enumeration. This isn't a problem if I just define the enumerations beforehand and pass them as template parameters to the base, however, since the enum type is directly related to the derived type, I want the enum to be defined within the derived class.
I was hoping to solve this by having the base class take the derived class as a parameter and then access the derived class's enum, like this:
template <typename child_type>
class base_type{
public:
int get_value(typename child_type::enum_type);
};
class child : public base_type<child>{
public:
enum enum_type{a,b,c};
};
MinGW reports
test.cpp: In instantiation of 'class base_type<child>':
test.cpp:7:22: required from here
test.cpp:4:6: error: invalid use of incomplete type 'class child'
int get_value(typename child_type::enum_type index);
^~~~~~~~~
test.cpp:7:7: note: forward declaration of 'class child'
class child : public base_type<child>{
^~~~~
I understand the errors; I just feel like there should be a way to do what I want to do and can't wrap my head around how to do it without getting too complicated. Is this possible, or am I going about it in the wrong way?
As for the specifics of my problem: the classes parse a record file which can be encoded in one of a few different encoding versions - the processing is mostly the same between versions and the bulk can be done in a non-virtual base function, with a call to a virtual function to do version-specific things. Different versions also extract slightly different value names, which I am trying to capture in the version-specific enums. The position of each named value inside the record will be stored in the value of the corresponding enum member value.
There's probably a better way to go about it but I haven't been able to think of it. I suppose in this case I could just have get_value take an int in the base class, use the child class enums to make the call, and just let the cast happen, but I was hoping to see if the more general case of a base class using a type defined in a child was possible.
The best solution I can think of is using child traits.
template <typename child_type>
class base_type{
public:
int get_value(typename child_type::enum_type);
};
struct child_traits {
enum enum_type{a,b,c};
};
class child :
public child_traits,
public base_type<child_traits>{
};
I've got an Inheritance problem:
Let's say I've got
class Time{
protected:
void foo();
};
and also
class Base: private Time{
void foo1(){ foo(); }
};
class Child: public Base, private Time{
void foo2(){ foo(); }// here my compiler says that foo is ambiguous
};
why is foo() ambiguous, if the inheritance of Time in Base is private?
PS.
Just&only for those who need to see the full code, here is the GitHub Project:
https://github.com/huntekah/Interior_decorator-OpenGL_Project/blob/master/Grafika-OpenGL/Interior_decorator/Display.cpp#L133
class Time( utilities directory ) is inherited by ControlObjects and ControlCamera, both of which are the base for Controls. Display inherits Controls , and additionally Time. commented line shows a place where SetDeltaTime() is ambiguous;
there's another error in your code: class base inherits privately from class Time and class Child inherits again privately from class time!!!
the law of inheritance:
class Time
{};
class Base : private Time
{};
class Child : public Base, private Time
{};
Base has a copy of class Time because it inherits from it.
child has a copy of class Base because it inherits from it.
*** Child has a copy of class Time because its parents (Base) has this copy.
if Child tries to inherit explicitly from class Time will issue a compile-time-error: error C2584: 'Child' : direct base 'Time' is inaccessible; already a base of 'Base'
Preliminary remarks
Your code snippet doesn't compile for another reason: Base has no access to Time's foo() as it is a private member. So the foo1() causes an error, before you have the reported ambiguity.
If you change Time to make its member protected, then you can reproduce your error exactly as you describe:
class Time{
protected:
void foo();
};
What's wrong here ?
Base privately inherits Time, so that it's members are not expected to be visible to the outside world.
But what could be true for the external world is not true for derived classes. The name lookup rules in the case of derivation say that first the name is looked up in the class hierarchy, then overloading is applied, than only is access control carried out:
10.2/1 Member name lookup determines the meaning of a name (id-expression) in a class scope. Name lookup can result in an
ambiguity, in which case the program is ill-formed. For an
id-expression, name lookup begins in the class scope of this; for a qualified-id, name lookup begins in the scope of the
nested-name-specifier. Name lookup takes place before access
control.
10.2/8 If the name of an overloaded function is unambiguously found, overloading resolution also takes place before access control.
Ambiguities can often be resolved by qualifying a name with its class
name.
As you use multiple inheritance:
Time
:
:
Base Time
\ :
\ :
Child
So you inherit twice a foo(), once via private inheritance and onve via public. This ambiguity makes the name foo in foo2() ambiguous according to the standard, and before access is verified, making your code invalid.
Note that Child sees 2 foo() but ironically can't use none of them: both come via private inherited. So even if you'd resolve the ambiguity, you'd get another error message about accessibility.
This is likely a basic question, but I haven't seen this done before and I haven't found a reference that talks about it:
What is going on in the following code:
using HandlerType = std::function<bool()>;
class SpecificAction : public Action<HandlerType>
{
public:
using Action::Action;
};
Specifically, what is the reason for the 'using Action::Action'? Action is a class template with a bunch of methods defined for it, but this is the entire declaration for SpecificAction.
When you are defining a class SpecificAction deriving from Action, everything in Action is added to SpecificAction, except the constructors. This syntax is a way to tell the compiler that you want to use the constructor from Action as a constructor for SpecificAction.
The reason constructor are not added by default to the derived class is that the derived class is likely to add some more data members which will not be initialized by the base constructor. Using this syntax you're telling the compiler that it's ok, you know what you're doing.
I have a library given to me where I am supposed to subclass one of its struct for use in my own app. When I do this, it works fine. However, when I change my subclass definition to class instead of struct (and I make sure to public: before everything inside), the compiler (Visual Studio compiler 10) gives me this odd error:
typecast: conversion exists but is inaccessible
The line on which this error occurs looks like this:
LibraryNameSpace::Client c(config_options, &mySublassObject);
I don't understand why a simple change from struct to class creates this error; any compiler-added default constructors would apply to either struct or class, including conversion constructors (if that's the issue here).
Is it perhaps because creating a class subclass from a struct base class is not a good idea?
Members of a 'struct' are public by default, whereas members of a 'class' are private by default. If you do not specify public/private, all members in the 'struct' become private when you change it to 'class'.
Also did you inherit by private or public?
class Subclass : public SuperClass {
public:
// ...
};
I recently ran into a problem when using a private inheritance scheme in which the base class defined a template method and the (privately) derived class made that method public via a using declaration under the public access specifier. The template was designed to take the address of a function and invoke that function pointer. However, upon attempting to pass the name of the function to the derived class template method, I receive an error message that states that the base-class method cannot access a private member declared in the derived class. Here is a code segment that models the issue:
class A
{
public:
template<class T> void Funct(T pFunct) { }
};
class B : private A
{
public:
using A::Funct;
};
void Show(void) { }
int main(void)
{
B b;
b.Funct(Show);
}
The exact resulting error message is: 'A::Funct' : cannot access private member declared in class 'B'
I am able to resolve the issue simply by:
1)Preceding the function argument name with the address-of operator:
b.Funct(&Show);
2)Explicitly qualifying the template type argument:
b.Funct<void(*)(void)>(Show)
If the Show() function were a template as well, I would need to explicitly qualify the template using the proper template type arguments used to instantiate Show.
My question is not how to solve the problem but why the error message is being generated. Why does instantiating Funct() with Show versus with &Show cause the compiler to do two different things. And why does instantiating Funct() with Show cause the Funct() method to attempt to access the private data in class B (which I'm assuming is the A subobject in class B)?
Compiles fine with Comeau Online. Ergo, compiler bug. Report it.
Cheers & hth.,
bcc32 gives error: error bccE2247: 'Funct<void (*)()>(void (*)())' is not accessible in function main()
I believe this is a compiler bug.