This question already has answers here:
What is the logic behind the "using" keyword in C++?
(2 answers)
Closed 2 years ago.
I know using in C++11 behaves same as typedef. I have this code and found different use cases:
template<typename T, int a>
class Base
{
public:
std::vector<T> noise_(a);
using VectorType = std::vector<T>;
virtual VectorType getVector() const
{
return noise_;
}
protected:
VectorType noise_;
};
template<typename T, int a>
class Derived : public Base<T,a>
{
public:
using Base<T,a>::noise_;
using VectorType = typename Base<T,a>::VectorType;
using Base<T,a>::getVector;
};
Here, using is used in 3 different way. What is the purpose of the following line (noise_ is a protected member of the base class):
using Base<T,a>::noise_;
Same for:
using Base<T,a>::getVector;
Simply put, when the base class depends on a template parameter, its scope is not inspected to resolve names. Hence, you cannot refer to noise_ in Derived using just noise_. You should either write this->noise_, or introduce the name with using.
Related
This question already has answers here:
Accessing type aliases in base class from derived class [duplicate]
(1 answer)
Why can't I use alias from a base class in a derived class with templates?
(3 answers)
Closed 13 days ago.
I'm working with some classes which are expected to perform as a singleton. My code works like this:
template <typename T>
struct Singleton {
public:
using SingletonType = T;
protected:
static T& getInstance() {
static T instance;
return instance;
}
};
struct NormalClass: protected Singleton<NormalClass> {
//The following three seem to be the same
//friend class Singleton;
//friend class Singleton<NormalClass>;
friend class Singleton<SingletonType >;
static const SingletonType& instance() {return Singleton<SingletonType>::getInstance();}
protected:
NormalClass();
};
But when I work with a template class, it forces me to explicitly declare the typename for Singleton and I cannot access Singleton::SingletonType
template <int N>
struct TemplateClass: protected Singleton<TemplateClass<N>>{
friend class Singleton<TemplateClass>; // It works fine
//friend class Singleton<SingletonType >; //error: 'SingletonType' was not declared in this scope;
protected:
int n;
TemplateClass():n(N){}
};
Could someone explain why to me? Thanks for your answer.
This question already has answers here:
Specializing `std::hash` for classes meeting condition
(3 answers)
Closed 1 year ago.
I have a class
class Base {
...
virtual size_t GetHash() = 0;
...
};
and a number of classes, inherited from Base, that override GetHash().
I want to use these classes as a key in unordered_map or unordered_set. Currently I achieve it by using
struct HashKey
{
template <typename T>
size_t operator()(const T & obj) const
{
return obj.GetHash();
}
};
as a Hash class in unordered_map template (like unordered_map<MyDerived, int, Hashkey>).
According to this question, I can explicitly specialize std::hash<T> for my own class and totally works fine, but I'm interested if there any way to specialize it for multiple classes?
I'm using C++17
Yes. Make it work for all T where T has a base class of Base.
Without requires, this is done using SFINAE and enable_if.
This question already has answers here:
C++ - Use enum from template class without template parameter
(2 answers)
Closed 3 years ago.
Is it possible to use the member struct or enum class of a templated class, without explicitly specifying the template arguments. So for ex:
template<typename A, typename B>
class Foo {
public:
enum class Status {E1, E2, E3};
};
void func() {
auto e = Foo::Bar::E1;
}
I guess I see the point that the compiler needs to instantiate Foo given its template arguments, but just wondering if there is a way around to still use its member class.
If the type is not really important and you just want access to the enum class, maybe you can typedef it
using Bar = Foo<void, void>;
void func() {
auto e = Bar::Status::E1;
}
I think your other option is to write the type explicitly or declare the enum class in namespace scope
C++ does not allow use of a Template class without passing template parameters. However there is a workaround if your requirement is not restricted to two template parameters.
The workaround:
You can define the class Foo as variadic template. This will enable you to use the enum without passing parameters to the class Foo. Example is below:
template<typename ...A>
class Foo {
public:
using Bar = enum class Status {E1, E2, E3};
};
void func() {
auto e = Foo<>::Bar::E1;
}
I am not sure if this will satisfy your requirement, but this will compile and work. I did compile it with c++17 flag.
This question already has answers here:
C++ template constructor
(10 answers)
Closed 7 years ago.
I have recently adopted the pattern of Almost Always Auto in C++14, but have come across a case that I can't figure out how to write using the auto syntax: templated constructors.
Say I have the class:
class my_type{
public:
template<typename T>
my_type(){/* ... */}
};
I tried:
auto var = my_type<float>{};
Which, of course, doesn't work because that presumes my_type is a template and not its constructor.
then how could I use auto syntax to initialize this variable?
Although it isn't really about auto, there is a way to select templated ctors if you want to - you need to cheat, and give them an argument.
struct A {
private:
template <typename T> struct TypeWrapper {};
template <typename T> explicit A(TypeWrapper<T>) {}
public:
template <typename T>
static A make_A() {
return A(TypeWrapper<T>{});
}
};
int main() {
auto i = A::make_A<int>();
auto d = A::make_A<double>();
auto r = A::make_A<A>();
// etc. etc.
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ Restrict Template Function
Is it possible to write a C++ template to check for a function's existence?
Is it possible to restrict the types for which a template may be instantiated
(that is, have a compiler error if I use template<type_not_allowed>)?
One way would be to provide no default implementation, and specialize your class template only on those types you wish to allow. For example:
#include <iostream>
using namespace std;
template<class X> class Gizmo
{
public:
Gizmo();
};
template<> Gizmo<int>::Gizmo()
{
}
int main()
{
Gizmo<float> gf; // ERROR: No specialization for Gizmo<float> results in a linking error
}
Make the constructor private in the illegal type:
template<typename T>
class Z
{
public:
Z() {}
};
template<>
class Z<int>
{
private:
Z();
};
Z<float> f; // OK
Z<int> i; // Compile time error.