Function template look-up issue [duplicate] - c++

This question already has answers here:
Why doesn't ADL find function templates?
(4 answers)
Closed 9 years ago.
Could someone please explain why the following code is giving error (error C2065: 'select' : undeclared identifier) at compile time:
namespace N {
class MyClass{
};
template<int I> void select(MyClass*)
{}
}
void g (N::MyClass* mp)
{
select<10>(mp);
}
void main()
{}
According to Argument Dependent Lookup, this should work fine, since I have specified N:: in `g``s argument. So, select should be visible to compiler.
Why does ADL not work here?

have you tried N::select?
either that or a
using namespace N
should work since simply select is not visible

Any time you utilise a class from a divergent namespace from the one you are currently in you must either reference it directly (N::select) or set up a using namespace (using namespace N;) or set up a direct using statement to it for future use (using N::select)
For disambiguation I would look at this and this , which between them should give you a good start on how/why you cannot simply call select.
Cheers, and feel free to get a hold of me for more info.

Related

C++; Pass std::array as a Function Parameter

I know this is a common question, but how do I pass a std::array as a function parameter? I've looked at answers for other questions on here asking the same thing, and the best "solution" I found was to use a template to set size_t to a keyword like SIZE. I tried this, but it still gives me two compile time errors:
Error C2065 'SIZE': undeclared identifier
Error C2975 '_Size': invalid template argument for 'std::array', expected compile-time constant expression
Both errors on the line where I have my void function definition.
As far as I know, I did this exactly how the solution was typed out. I know I could instead pass through a std::vector, but I'm stubborn and want to learn this.
Here is my relevant code:
#include <iostream>
#include <array>
using namespace std;
template<size_t SIZE>
void QuickSort(array<unsigned, SIZE>& arrayName);
int main()
{
// main function.
}
void QuickSort(array<unsigned, SIZE>& arrayName)
{
// whatever the function does.
}
I'd appreciate any help figuring out what it is that I'm doing wrong.
EDIT: I forgot to take out the second function parameter. I did that, but still the same issues.
Your function definition still needs template parameters since the compiler has no way of knowing what SIZE is
template<size_t SIZE>
// ^^^^^^^^^^^^^^^^^^
void QuickSort(array<unsigned, SIZE>& arrayName)
{
/// whatever the function does.
}

No conflicts with the variable decleare inside the main and the one decleare inside the namspace [duplicate]

This question already has answers here:
How can I access a shadowed global variable in C?
(6 answers)
Closed 3 years ago.
I'm studying c++ namespace and i made a simple code to understand it. In particular i made this code and i don't understand why it doesn't give me the compiler error that i'have already decleare the variable 'a'. Is the compiler help me in some way?
#include<iostream>
using namespace std;
namespace funzioni_e_altro
{
int a=5;
int b=20;
int c=10;
}
int main()
{
using namespace funzioni_e_altro;
int a=0;
cout<<funzioni_e_altro::a<<"\n";
cout<<b<<"\n";
cout<<a<<"\n";
return 0;
}
I expect it gave me a compiler error, but it gave me the outputs:
5
20
0
A using directive makes the names in the namespace available for unqualified name lookup. But it doesn't introduce any new declarations into the block. When you declare a in main it hides the name the using directive could have brought in. That a is no longer considered during unqualified name lookup inside main.
So when you write a in main, it can only refer to the local variable. Same as if there was no using directive present at all in main.
This behavior is intended. It prevents complete an utter chaos from happening. A using directive should not prevent code from declaring a name in its own scope if it needs to. And you may always refer to the variable in the namespace by fully qualifying its name.

C++ strange namespace lookup behavior [duplicate]

This question already has answers here:
Injected class name compiler discrepancy
(3 answers)
Closed 6 years ago.
namespace fooo {
class Fooo {
public:
int a;
};
}
namespace fooo {
class Test {
public:
Test(Fooo::Fooo *i) {
i->a = 1;
}
};
}
This code compiles fine with clang (any version) but fails with gcc.
Can anyone explain why?
EDIT:
Yes, I know the issue here is kinda obvious but why does clang accept it? The person who told me this said that this is a bug in the standard and that there is a Defect Report. Can anyone point to the actual DR?
The error message from gcc tells you exactly what the problem is:
t.cpp:11:16: error: ‘fooo::Fooo::Fooo’ names the constructor, not the type
Test(const Fooo::Fooo *i) {
^
it is suprising that clang doesn't give an error.

redefinition of 'WhatEver' as different kind of symbol [duplicate]

This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 9 years ago.
I'm trying to migrate some legacy code into a newer project and I don't really get this one fixed. The code compiled and worked well in the older environment.
I have a header file which contains these definitions:
std::string ToString(shared_ptr<const SomeObject> obj);
std::string ToString(SomeObject* obj);
And an implementation file with following lines:
using namespace std;
string ToString(shared_ptr<const SomeObject> obj)
{
// code cut
return outstring.str();
}
string ToString(SomeObject* obj)
{
// code cut
return outstring.str();
}
I'm trying to compile it with clang and I get the following redefinition error:
.../Filename.cxx:15:8: error: redefinition of 'ToString' as different
kind of symbol
string ToString(shared_ptr<const SomeObject> obj)
^
.../Filename.h:15:13: note: previous definition is here
std::string ToString(SomeObject* obj);
Why is it a redefinition as different kind of symbol? How should I fix this? And last but not least, why does it work with older compilers?
Check if string and shared_ptr are declared, and try specifying namespaces for them (replace shared_ptr with boost::shared_ptr or std::shared_ptr) to make sure that the same class is used in declaration and implementation of ToString.

Detect if a type exists in C++ [duplicate]

This question already has answers here:
How to detect existence of a class using SFINAE?
(4 answers)
Closed 6 years ago.
I'd need a template which can be called like this:
int x = type_exists< std::vector<int> >::value;
This should set x to 1 if #include <vector> was present (either explicitly or transitively) earlier in the source, otherwise it should set x to 0.
Is it possible to do it in C++? I'm using GCC, so GCC extensions are also fine.
It's also OK to change the call syntax a bit.
It's not OK to run the C++ compiler twice: first just to figure out if we get a compile error.
This is not what you are looking for, but it's as close as you can get to a type_exists trait:
template<class T> struct Void { typedef void type; };
template<class T, class U = void>
struct type_exists { enum { value = 0 }; };
template<class T>
struct type_exists<T, typename Void<T>::type> { enum { value = 1 }; };
Apparently, it works:
static_assert(type_exists<int>::value, "int is not defined");
static_assert(type_exists<SomeNonexistingType>::value, "expected compile-time error");
This does exactly what it is supposed to do. Tested with GCC 5.4.0.
This is not possible, I'm afraid. If we were to use a non defined identifier we would get a compilation error, leading to this code:
int x = type_exists< std::vector<int> >::value;
not to even compile.
Also, the standard doesn't specify any preprocessor directive to be declared within the header file (which is implementation defined instead) for the standard library, therefore you won't be able to detect it even with preprocessor macros.