6

When using std::weak_ptr, it is best practice to access the corresponding std::shared_ptr with the lock() method, as so:

std::weak_ptr<std::string> w; std::shared_ptr<std::string> s = std::make_shared<std::string>("test"); w = s; if (auto p = w.lock()) std::cout << *p << "\n"; else std::cout << "Empty"; 

If I wanted to use the ternary operator to short hand this, it would seem that this:

std::cout << (auto p = w.lock()) ? *p : "Empty"; 

would be valid code, but this does not compile.

Is it possible to use this approach with the ternary operator?

4
  • 1
    All parts of a conditional expression are in turn expressions. You can't have definition of variables in expressions. Commented Oct 1, 2021 at 22:44
  • 2
    Somewhat related: what's an expression and expression statement in c++? and Expression Versus Statement. Declarations are not expressions in C++, so it won't be possible to declare p inside of the first expression of ?:. However, assignments are expressions, so something like (p = w.lock()) ? *p : "Empty" would be valid, assuming p was already declared. Commented Oct 1, 2021 at 22:49
  • 1
    You could declare p outside the ternary and then assign it inside, but then you can't use the placeholder auto. It'd be std::shared_ptr<std::string> p; std::cout << (p = w.lock()) ? *p : "Empty"; Commented Oct 1, 2021 at 23:34
  • @NateEldredge you might not be able to use auto in that case, but you can still deduce the shared_ptr type from the weak_ptr, by using std::shared_ptr<decltype(w)::element_type> p;, or even simpler decltype(w.lock()) p; Commented Oct 2, 2021 at 15:21

2 Answers 2

4

auto p = w.lock() is not an assignment. It's a declaration of a variable. You can declare a variable in the condition of an if statement, but you cannot declare variables within a conditional expression.

You can write:

auto p = w.lock(); std::cout << ( p ? *p : "Empty" ); 
Sign up to request clarification or add additional context in comments.

Comments

3

If you want to introduce a variable for an expression (like let in Lisp or Haskell), you can use a lambda:

std::cout << [p = w.lock()] {return p ? *p : "Empty";}(); 

This also confines the ?:, which interprets std::cout as part of the condition in your question.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.