Specialization of 'templateclass _Tp struct std::less' in different namespace
This is still the way to do it. Unfortunately you cannot declare or define functions within a namespace like you would do with a class: you need to actually wrap them in a namespace block.
warning: specialization of template in different namespace
Assuming that you are compiling this in C++11 mode (since clang gave no warning) and that this specialization is in the global namespace, then there's nothing wrong with your code. It's a g++ bug. §14.7.3 [temp.expl.spec]/p2:
An explicit specialization shall be declared in a namespace enclosing
the specialized template. An explicit specialization whose
declarator-id is not qualified shall be declared in the nearest enclosing namespace of the template, or, if the namespace is inline
(7.3.1), any namespace from its enclosing namespace set. Such a
declaration may also be a definition. If the declaration is not a
definition, the specialization may be defined later (7.3.1.2).
The global namespace is a "namespace enclosing the specialized template", and your declarator-id is qualified with std::
, so the second sentence doesn't apply. As a workaround, you can do what cdhowie's answer suggests - i.e., opening a namespace std
block and putting the specialization there.
See CWG issue 374 and GCC bug 56480.
Resolution of class template with different default template argument and partial specialization argument
If I understand the confusion, when you see
/* primary class template B */
template <int N, class = void>
struct B : std::false_type {};
/* partial specialization of B */
template <int N>
struct B<N, std::enable_if_t<(N != 0), int>> : std::true_type {};
You think that when the compiler sees B<1>
in main
,
- it sees that the general template is ok,
- then it goes to see the specialization and
- sees that
(N != 0)
istrue
, - resolves
std::enable_if_t<(N != 0), int>
toint
- thus resulting in
B<1, int>
, which is good and to be preferred since it is a specialization.
- sees that
The story is slightly different.
The line
template <int N, class = void>
just means, as suggested in a comment, that when you write B<an-int>
the compiler sees B<an-int, void>
.
If you look at it from this perspective, you should see why the mismatch causes the behavior you observe: B<1>
is just B<1, void>
, and no specialization is targeting that.
Defining a template specialization in an anonymous namespace (and compile error C2888)
A symbol belonging to namespace std
must be defined in a namespace that encloses std
which means that you'll have to define it in the global namespace.
Here's an example from C2888:
namespace M {
namespace N {
void f1();
void f2();
}
void N::f1() {} // OK: namspace M encloses N
}
namespace O {
void M::N::f2() {} // C2888 namespace O does not enclose M
}
[temp.expl.spec/9]
from the C++20 draft:
A template explicit specialization is in the scope of the namespace in which the template was defined. [ Example:
namespace N {
template<class T> class X { /* ... */ };
template<class T> class Y { /* ... */ };
template<>
class X<int> { /* ... */ }; // OK: specialization in same namespace
template<>
class Y<double>; // forward-declare intent to specialize for double
}
template<>
class N::Y<double> { /* ... */ }; // OK: specialization in enclosing namespace
template<>
class N::Y<short> { /* ... */ }; // OK: specialization in enclosing namespace
— end example ]
Partial specialization tempate c++
Look at this function declaration:
void frob(float f, bool g = true) {
// ...
}
As you might know, you can drop parameter name from declarations:
void frob(float f, bool = true) {
// ...
}
You can also set the default value using an expression. This is equivalent as the previous example:
void frob(float f, bool = std::is_floating_point<float>::value) {
// ...
}
Then, let's add a simple template for the sake of the exercise:
template<typename T>
void frob(T f, bool = std::is_floating_point<T>::value) {
// ...
}
Technically, you could move parameters to be template parameters, if you know them at compile time:
template<typename T, bool = std::is_floating_point<T>::value>
void frob(T f) {
// ...
}
Now it's beginning to look like your own template declaration isn't it?
Now that you understand the syntax, let's see how it's useful with partial specialization.
Imagine you're the compiler and you expand the template instantiation of ElementType
for float
and std::integral_constant<int, 0>
:
template<>
struct ElementType<float, std::is_floating_point<float>::value> { ... };
template<>
struct ElementType<
std::integral_constant<int, 0>,
std::is_floating_point<int>::value
> { ... };
Expands the constants, you get this:
template<>
struct ElementType<float, true> { ... };
template<>
struct ElementType<std::integral_constant<int, 0>, false> { ... };
Now that you expanded this, you see that you have both true and false as the second parameter. You pick the specialization for each:
template<>
struct ElementType<float, true> { using Type = float; };
template<>
struct ElementType<std::integral_constant<int, 0>, false> {
// int
using Type = typename std::integral_constant<int, 0>::value_type;
};
namespace specialization in template class
using namespace
is not allowed in class scope, nor is namespace alias. I don't think you can do a specialization that would somehow inject the namespace.
It's not exactly the same, but if it's an option to declare all the functions you need from that namespace in the specialization, you can make the function pointer as a member of that specialization:
template <names>
struct base_class;
template <>
struct base_class<names::first>
{
static constexpr auto test = &one::test;
};
template <>
struct base_class<names::second>
{
static constexpr auto test = &two::test;
};
template <names ns>
struct delcare_namespace : public base_class<ns>
{
delcare_namespace()
{
std::cout << this->test() << "\n";
}
};
How to define less than () operator or std::less struct for Eigen::Vector3f?
It is generally a really bad idea to use floating point values (or aggregates) as keys into a map.
That is a fundamental design issue. I mean, if there is a NaN, everything explodes. And two seemingly identical derivations of a floating point value can compare unequal.
But it isn't hard to write a comparison operator.
struct LexographicLess {
template<class T>
bool operator()(T const& lhs, T const& rhs) const {
return std::lexographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
};
then simply do:
std::map<Eigen::Vector3f, uint32_t, LexographicLess>;
we can fix the "NaN" issue:
template<class L=std::less<>>
struct LexographicLess {
template<class T>
bool operator()(T const& lhs, T const& rhs) const {
return std::lexographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), L{});
}
};
which lets us pass in a "sub-less", which we can harden against NaN
issues.
Doing this right will depend on the framework of your problem. Does your space have to support locations that vary from layout of gates on a integrated circuit all the way to locations light years away? If not, you could reconsider using floating point values.
Second, spacial mapping using a one-dimensional ordered map like std::map
is often a bad idea. Learn what a Quad and Octtree are, which organize things in 2 or 3 dimensions so that nearby things are nearby in the data structure.
The question "what are the values of this function near this coordinate" is far more sensible to ask of a continuum approximation (like 3 dimensional floats) than "what is the value stored for this exact point", which is near nonsense on a continuum, and doesn't work well in a floating point continuum approximation.
But that is far, far out of scope.
Related Topics
Array of Pointers as Function Parameter
Recursion in C++ Factorial Program
How to Enforce the 'Override' Keyword
Ways to Detect Whether a C++ Virtual Function Has Been Redefined in a Derived Class
Narrowing Conversion from Unsigned to Double
How to Recursively Create a Folder in Win32
What Is the Purpose of a Declaration Like Int (X); or Int (X) = 10;
Get Std::Fstream Failure Error Messages And/Or Exceptions
Is There a Standard Date/Time Class in C++
How to Tell Reliably If a Boost Thread Has Exited Its Run Method
Is It Safe to Memset Bool to 0
Two Classes That Refer to Each Other
How Copy from One Stringstream Object to Another in C++
Can't Compile Easy Source in C++ and Opengl (Glfw) in Linux in Netbeans