This question already has answers here:
Alias template specialisation
(4 answers)
Closed 10 months ago.
I am learning about C++ templates from C++ Primer 5th edition. For example, i learnt that we could do the following:
template<typename T>
struct Custom
{
};
template<>
struct Custom<int>
{
int a = 0;
};
Then i learnt that C++11 also added a feature of alias templates. So i tried the same with them as shown below:
template<typename T>
using var = std::stack<T>;
template<>
using var<double> = double;
But the above shown snippet doesn't work. What is the problem here, why doesn't the 2nd snippet work.
The problem is that we cannot specialize an alias templates.
From temp.decls 17.5.3:
Because an alias-declaration cannot declare a template-id, it is not possible to partially or explicitly specialize an alias template.
Related
This question already has answers here:
What does a template class without arguments, `template<>` mean?
(1 answer)
In C++ what does template<> mean?
(3 answers)
Closed 1 year ago.
I was looking for how to use YAML in LLVM. And I don't understand why they use empty templates. For example, here.
template <>
struct ScalarEnumerationTraits<FooBar> {
static void enumeration(IO &io, FooBar &value) {
...
}
};
What is the template <> for?
This is not a duplicate of What is the meaning of empty "<>" in template usage?.
This is a template specialization. You will find somewhere something like:
template <typename C>
struct ScalarEnumerationTraits;
And the thing you are seeing is the specialisation of that declaration for the type FooBar.
This question already has answers here:
std:: add_pointer, what the try_add_pointer for in the possible implementation?
(2 answers)
Closed 2 years ago.
I've been hacking around the standard library lately, since I need to implement a subset of it (mostly template stuff) for a system which doesn't have an stdlib implementation.
I came across this "possible implementation", in cppreference:
namespace detail {
template <class T>
struct type_identity { using type = T; }; // or use std::type_identity (since C++20)
template <class T>
auto try_add_pointer(int) -> type_identity<typename std::remove_reference<T>::type*>;
template <class T>
auto try_add_pointer(...) -> type_identity<T>;
} // namespace detail
template <class T>
struct add_pointer : decltype(detail::try_add_pointer<T>(0)) {};
and I've been wondering why do you need SFINAE here. Isn't this:
template< class T >
struct add_pointer {
typedef typename std::remove_reference<T>::type* type;
};
enough? which instantiation takes the second case of try_add_pointer? I tried to think about it but couldn't think about any such case.
I'm not sure if this is the only bad case, but your implementation fails for so-called "abominable function types":
add_pointer<void() const>::type // hard error instead of void() const
This question already has answers here:
Member function template selection and SFINAE
(1 answer)
SFINAE not working to conditionally compile member function template
(1 answer)
Approaches to function SFINAE in C++
(2 answers)
Closed 2 years ago.
I want to switch between to members of a templatized class based on the fact the type of the template is default constructible or not.
I think I'm not far from the solution after a lot of reading and tries around std::enable_if and std::is_default_constructible, but I'm still stuck at compile-time, here's a minimized exemple :
template<typename DataType>
class MyClass{
public:
template < typename = typename std::enable_if_t<std::is_default_constructible_v<DataType>>>
inline void createNew(unsigned int index) {
new (&this->buffer[index]) DataType(); // "placement new"
}
template < typename = typename std::enable_if_t<!std::is_default_constructible_v<DataType>>>
inline void createNew(unsigned int index) {
throw BaseException("No default constructor");
}
};
This last try results on "member function already defined or declared". I think I miss something, but I don't understand why both functions are selected for compilation even if they have the exact opposite template condition.
This question already has answers here:
Is it possible to define an alias for a template-template parameter?
(2 answers)
Closed 3 years ago.
I have the following piece of code which does not compile -> http://ideone.com/bL9DF1.
The problem is that I want to get the template template parameter out of a type. What I have is using S = A<int, std::vector> and I want to get back that I used std::vector in making S and to use it somewhere else.
#include <iostream>
#include <vector>
template <typename T, template<class...> class Container>
struct A
{
using Ttype = T;
using ContainerType = Container;
Container<T> s;
};
int main()
{
using S = A<int, std::vector>;
S::ContainerType<double> y;
y.push_back(2);
return 0;
}
I don't know if there is even a way of doing what I want. Without the template parameters added std::vector is not a type.
You could declare ContainerType as an alias template, since Container is a template itself.
template<typename... X>
using ContainerType = Container<X...>;
LIVE
This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 3 years ago.
I found this article:
https://tristanbrindle.com/posts/beware-copies-initializer-list
and I have some question about part of the presented code:
First:
I think that is something about dependent name but I am not sure what is a purpouse of this part:
template <typename T>
typename instance_counter<T>::counter instance_counter<T>::icounter{};
And second one:
template <typename T>
struct counted : T, private instance_counter<T>
{
using T::T;
};
Could somebody give me an explanation about these codes?
Could somebody give me an explanation about these codes?
template <typename T>
typename instance_counter<T>::counter instance_counter<T>::icounter{};
This is the initialization of a static variable declared in the instance_counter template (see the static struct counter { /* ... */ } icounter; in the blog post). See this thread for more info on the initialization of static data members. The definition refers to a nested name of a template (counter), and the compiler defaults to consider it a name for a value, not a type. To change this default interpretation, you need to prepend typename. See this thread for details.
template <typename T>
struct counted : T, private instance_counter<T>
{
using T::T;
};
Here, the template counted inherits publicly from T (public inheritance is the default for structs) and privately from instance_counter<T>. The public inheritance part together with using T::T (which brings in all ctor overloads of T) is used to provide the same interface as the class the template is instantiated with (e.g. string in the post). The private inheritance part means is-implemented-in-terms-of and makes sure the instance_counter machinery is pulled in for the newly instantiated class type, with the output being generated in the destructor.