is it possible to alter the Pair function to make it use 3 elements?
Printable View
is it possible to alter the Pair function to make it use 3 elements?
What pair function are talking about ?
Check out the <tuple> standard library if your compiler is new enough to support it. Otherwise, you can get it from Boost.
Would this fit?
Code:std::pair<int a , std::pair < int b, int c >>
Thanks problem solved!(Y)
Personally, I've never been a fan of 'pair'. I only ever use it when I have to to interface with certain STL containers.
By combining them, it gets even worse!
It doesn't do much for readability or maintainability. :sick:Code:std::pair<int a , std::pair< std::pair < int b, int c >, int d>> quad;
quad.second.first.second; // Actually 'c'!
My only gripe with pair is that it has tought me 1-based index (first second), whereas the tuple equivalent is 0-based index. Oh No!
the equivalent tuple:Code:auto my_pair = std::make_pair(1, "Hi!");
my_pair.first = ...
my_pair.second= ...
However:Code:auto my_tuple = std::make_tuple("hello", "world!");
std::get<0>(my_tuple)= ... ; //equivalent to "first"
std::get<1>(my_tuple)= ... ; //equivalent to "second"
----Code:auto my_tuple = std::make_tuple("hello", "world!");
std::get<1>(my_tuple)= ... ; //NOT equivalent "first"
std::get<2>(my_tuple)= ... ; //Creates a terrible terrible compilation message
On a side note, anybody now why this doesn't work?
Isn't Koenig (Argument-dependent name) lookup was specifically designed to support this use case?Code:get<1>(my_tuple);
//In function 'int main()':
//error: 'get' was not declared in this scope
//note: suggested alternative:
//note: 'std::get'
speaking about std:: pair
in theory, there's nothing wrong with std:: pair, as long as one uses it with consistent semantics, that is to represent a set of two things of which one is intuitively and exhaustively interpreted as first and the other as second.
the problem is that the STL itself uses pair the wrong way, as the associative containers insert methods. Personally, I would have preferred a dedicated ( but general ) type template, something like an insertion_point<Iterator> exposing an iterator and a boolean value with descriptive names or with a convenient interface ( a la boost:: optional: an operator* exposing the iterator and an explicit operator bool exposing the boolean "already inserted" content ) ...
Just a small niggle, but I would have liked std::map (which has key/value semantics) to have contained something like 'std::keyvalue' with the members 'key' and 'value', rather than using a generic 'pair' for the job, but we're stuck with it now. I like my variables to mean what they say.
I see, but what exactly does "unless there is a function template with that name visible at the point of the call" mean?Quote:
Originally Posted by superbonzo;n3242
If I get this correctly, it means you can add "using std::get", at which point, ADP would activate? Which would further mean that if I wrote a md::tuple, then it would call my md::set because I declared using std::set?
yes
no, I don't think so. It just means that once the compiler gets aware of the fact that a name is a function template name ( and not a syntactical coincidence due to <,> operators ) then usual lookup rules kick in searching for a function template with a matching signature.
For example
Code:namespace A { struct X{}; template <class T> void f( const T& ); }
namespace B { template <class T> void f( T& ); }
int main()
{
using namespace B;
f<A::X>( A::X() ); // ok, matches A::f via ADL
}
Hum... You say "no", but then you appear to be showing an example where it does work...
In this example (that also works), I did not specify the all the template parameters. Do you view this as different from what your example was showing?
I find it super awesome that declaring "using A::f" is sufficient to bring into view and resolve a call to B::f. Goodness I love learning.Code:namespace A
{
template <typename T>
struct A_class
{ };
template<int N, typename T>
void f(A_class<T>&)
{ }
}
namespace B
{
template <typename T>
struct B_class { };
template <int N, typename T>
void f(B_class<T>&)
{ }
}
int main()
{
using A::f;
B::B_class<int> b;
f<0>(b);
}
EDIT: PS: I tried to rate your post, but it would appear you have already given me such useful advice in the past that I need to spread reputation to others first :D
no I don't, they do show the same phenomenon. Probably, I misunderstood your last question in post #11 where you said that "if I wrote a md::tuple, then it would call my md::set because I declared using std::set" that, once transposed to your example, I read as if the line "using A::f;" were replaced by "using A::A_class;" that does not work instead.