Jump to content


Nice C++ riddle/problem


29 replies to this topic

#21 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 06 June 2007 - 11:33 AM

Let's continue :P

#include <iostream>

namespace A
{
    const char str[] = "A::str";
}

namespace B
{
    const char str[] = "B::str";

    void foo1()
    {
        using namespace A;
        std::cout << str << std::endl;
    }

    void foo2()
    {
        using A::str;
        std::cout << str << std::endl;
    }
}

int main()
{
    B::foo1();
    B::foo2();
}

What does this output, and why?
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#22 poita

    Senior Member

  • Members
  • PipPipPipPip
  • 322 posts

Posted 06 June 2007 - 05:17 PM

It outputs B::str then A::str.

My guess at why would be because "using namespace" simply adds the members of the namespace to the lookup list but gives them lowest precedence when choosing from name conflicts. With "using A::str" the compiler treats A::str as if it were a local variable so it has precedence over the B::str.

#23 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 06 June 2007 - 08:12 PM

Quote

My guess at why would be because "using namespace" simply adds the members of the namespace to the lookup list but gives them lowest precedence when choosing from name conflicts

Not entirely true
namespace A
{
    static const char str[] = "A::str";

    namespace B
    {
         static const char str[] = "A::B::str";
    }

    void foo1()
    {
        using namespace B;
        std::cout << str << std::endl;  // error, str is ambiguous
    }

    namespace C
    {
        namespace D
        {
            const char str[] = "A::C::D::str";
        }

        void foo2()
        {
            using namespace D;
            std::cout << str << std::endl; // uses A::C::D::str
        }
    }
}

Indeed for a using declaration ("using A::str;"), it introduces the name in the current scope. For using directives ("using namespace A;") however, the name is introduced in the nearest enclosing namespace that contains both the current scope and the referred namespace.

In the first example, in B::foo1(), B::str has priority over A::str because the nearest enclosing namespace containing both B::foo1 and A is the global namespace, so B::str hides A::str.

In the example above, in A::B::foo1(), the nearest enclosing namespace containing A::B and A::foo1() is A. However, A itself also has a str, so A::str and A::B::str are on the same level within the context of foo1() and 'str' is therefore ambiguous.
In A::C::foo2(), the nearest enclosing scope containing A::C::D and A::C::foo2() is A::C. Therefore A::C::D::str hides the definition of A::str within the context of foo2()
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#24 poita

    Senior Member

  • Members
  • PipPipPipPip
  • 322 posts

Posted 07 June 2007 - 10:54 AM

:S

Interesting stuff!

Any more? :)

#25 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 07 June 2007 - 11:50 PM

I'm running out of ideas :P

#include <iostream>

void bar(int) { std::cout << "::bar()" << std::endl; }

namespace A
{
    struct AStruct { operator int() { return 0; } };
    void bar(AStruct) { std::cout << "A::bar()" << std::endl; }

    template<class T> void foo(T t)
    {
        bar(t);
        (bar)(t);
    }
}

namespace B
{
    struct BStruct { operator int() { return 0; } };
    void bar(BStruct) { std::cout << "B::bar()" << std::endl; }
}

int main()
{
    A::AStruct a;
    B::BStruct b;
    A::foo(a);
    A::foo(B);
}

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#26 chombik

    New Member

  • Members
  • Pip
  • 1 posts

Posted 17 June 2007 - 11:13 PM

C++ 3.11
How to increase an output scrolling to see all the print out?
I know this is not a nice C++ problem, but no one replied so far anywhere.
Please, help.

#27 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 18 June 2007 - 12:15 AM

C++ has no version, and C++ does not know the concept of a "screen". Your question has nothing to do with C++. Open a different topic for your question, and state your platform (linux, windows, etc.)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#28 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 04 July 2007 - 11:35 AM

.oisyn said:

I'm running out of ideas ;)

#include <iostream>

void bar(int) { std::cout << "::bar()" << std::endl; }

namespace A
{
    struct AStruct { operator int() { return 0; } };
    void bar(AStruct) { std::cout << "A::bar()" << std::endl; }

    template<class T> void foo(T t)
    {
        bar(t);
        (bar)(t);
    }
}

namespace B
{
    struct BStruct { operator int() { return 0; } };
    void bar(BStruct) { std::cout << "B::bar()" << std::endl; }
}

int main()
{
    A::AStruct a;
    B::BStruct b;
    A::foo(a);
    A::foo(:);
}
Nobody has an answer?

Any way, here's another one:
how many consecutive characters (without spaces etc) of the following symbols can you use in a valid C++ program?
a) '+'
:) '&'
c) '<'
d) '?'
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#29 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 04 July 2007 - 04:48 PM

I'll assume excluding comments, since you can repeat as many of any of those symbols as you like in a comment. ;)

(a) unlimited (c++; c++++; c++++++; ...)
(:) 3: if (foo &&&bar)
© 3: I'm not sure if this is legal...
struct foo {};
template <typename T>
operator << (const foo& lhs, T rhs);
// ...
foo a;
operator <<<int> (a, 0);
(d) 3:
a ???/
b : c;
where ??/ is the trigraph for \, here acting as an escaped newline in the middle of the conditional-expression.

So how'd I do? :)
reedbeta.com - developer blog, OpenGL demos, and other projects

#30 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 04 July 2007 - 09:14 PM

B) and c) are wrong, but for c) you're in the right direction, and for a) you're only including an even number of characters in your example ;)

a) unlimited: +c, ++c, +++c, ++++c, etc.
You'll need to at least overload the unary + to return an l-value for an uneven number. Another solution is to overload the postfix ++ to return l-value, so you can finish it with the binary + for an uneven number: c+++++d

B) 5: &MyStruct::operator&&&&&a, which is parsed as: &SomeStruct::operator&& && &someVar
So you're and'ing a pointer-to-member-function with another pointer

c) 4: &MyStruct::operator<<<<someVar
You'll need to overload the global << operator to be able to 'shift' a pointer-to-member-function with a user defined type :)

For d) I was indeed looking for the trigraph sequences :)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users