Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jul 29 2015 07:11
    日本語のC++チャットルームです。C++に関連する話題であればなんでも自由に投稿・質問してください。
  • Jul 29 2015 07:10
    日本語のC++チャットルームです。C に関連する話題であればなんでも自由に投稿・質問してください。
  • Jul 29 2015 07:09
    日本語のC チャットルームです。C に関連する話題であればなんでも自由に投稿・質問してください。
  • Jul 29 2015 07:07
    てすと from nyaocat
nyaocat
@nyaocat
んーでもそれだと msvc が使えなさそう…
Kohei Takahashi
@Flast
むずかしいこといいはる...
C++の話しよう
あるmovable type Tをreturn typeとして持つ関数fがあった時に、return文にid-expressionでローカル変数渡すとcopyではなくmoveされるわけですけど、tupleで多値をしようとしたときに、id-expressionではなくなってしまってcopyになるから、std::moveで囲ってやる必要があって、冗長すぎて大変なんですが、なんか良いソリューションとかないですかね...
nyaocat
@nyaocat
using namespace std;

tuple<unique_ptr<void>,  unique_ptr<void>>  func() {
   unique_ptr<void> lhs, rhs;

   return { move(lhs), move(rhs) };
}
この return 中での move 書くのがめんどい、ということであってますでしょうか
Kohei Takahashi
@Flast
そでーす
.oO(example書くのはやいなぁ
nyaocat
@nyaocat
まぁコンパイル通してない一発書きなので……。コードがインラインで綺麗に表示されるのは Gitter 中々良いですね
Kohei Takahashi
@Flast
話しそれますがインラインで書くのってmarkdownと同じ?
nyaocat
@nyaocat
そして考えてみるも中々思いつかない、こういうのいつも面倒だなぁと思いながら std::move 書いてた記憶
チャット欄の右下の書類のようなマーク押すと記法見れますですね。Markdownと同じです。
Kohei Takahashi
@Flast
そう、名前的にstd::forward_as_tupleがそんな感じだっけって思ってしまって使うんだけど、これはmake_tupleと違って、lvalueをlvalue refにして渡すだけで、lvalueをrvalue refにはしないからこういう場合に使えないんですよね
nyaocat
@nyaocat
使えたとしても forward_as_tuple と書くのが今度は面倒そう()
Kohei Takahashi
@Flast
return {std::move(x), std::move(y)};

return std::forward_as_tuple(x, y);

か、確かに2ぐらいだったら変わらないかもしれない...

nyaocat
@nyaocat
矢張りソレ用にヘルパ関数を定義しないとどうにもならなさそうな
move_as_tuple とか?
Kohei Takahashi
@Flast
用途を考えるとmove_as_tupleがたしかにmake senseだなぁ
Cryolite
@Cryolite
std::forward_as_tuple も std::move を明示的に書かないと使えないのでは?
あと疑問の趣旨と全然関係ないですが, void は不完全型なので default_deleter のまま unique_ptr<void> 使うと dtor で怒られるっていう話があってですね.
Kohei Takahashi
@Flast
そう、名前的にstd::forward_as_tupleがそんな感じだっけって思ってしまって使うんだけど、これはmake_tupleと違って、lvalueをlvalue refにして渡すだけで、lvalueをrvalue refにはしないからこういう場合に使えないんですよね
使えたとしても forward_as_tuple と書くのが今度は面倒そう()
使えたとしても <-- ココテストに出る
nyaocat
@nyaocat

あと疑問の趣旨と全然関係ないですが, void は不完全型なので default_deleter のまま unique_ptr<void> 使うと dtor で怒られるっていう話があってですね.

そういえば確かに…… せめてint とかにしておけば良かったですね。まぁ趣旨とは関係ないとこなんですが

Cryolite
@Cryolite
あ,すんまそん.普通に見落としてましたん.>使えたとしても
Kohei Takahashi
@Flast
そうだ、std::tuple<T...>::tuple(std::tuple<U...>&&)はexplicitなので、結局std::make_tupleを使わざるを得なくて、とても長くなるので、なんとかならないかなって思ってたんだった
return {std::move(x), std::move(y)}; // error
return std::make_tuple(std::move(x), std::move(y)); // ok
ままならぬ...
nyaocat
@nyaocat
あ、explicitだったか……。make_tupleにmoveも書かねばならないとなると、やろうとしてる事に対してコードが長くてなんか嫌ですねこれ
Kohei Takahashi
@Flast
おっとみす std::tuple<T...>::tuple(std::tuple<U...>&&)これじゃなくて std::tuple<T...>::tuple(U...&&)こっちがexplicit
arithmeticae
@marionette-of-u
はじめまして。C++03以降がLR(1)クラス構文って本当ですか。オペレーターオーバーロードがあるからっていう理由を聞いたのですがいまいち納得できません。
nyaocat
@nyaocat

構文解析については詳しくないので、 https://ja.wikipedia.org/wiki/LR%E6%B3%95 を読んだのですが、この記事中に

多くのプログラミング言語がLR法(およびそれを一部改変したもの)で構文解析できる。例外として、C++とPerlがある。

との記述がありますね。

Wikipediaには理由は書いてませんが、うろ覚え知識だと、 A * B ; とあった際にこの文だけではABの乗算なのかA*型の変数Bの宣言なのか区別が付けられないので、一般的な構文解析が出来ない、とどこかで読んだ気がします。
オペレーターオーバーロードが関係するかは……僕の知識不足で分かりません。
nyaocat
@nyaocat

オペレーターオーバーロードがあるから

という記述の出典元を示して下さると、他の方が答えやすくなるかもしれません。

Kohei Takahashi
@Flast
適当にぐぐったらこんなエントリが見つかりました
http://d.hatena.ne.jp/kazu-yamamoto/20081201/1228115457
arithmeticae
@marionette-of-u
オペレーターオーバーロードが理由という話は昔StackOverflowで見かけました。
nyaocat
@nyaocat
stackoverflowに C++ が LR で解析できないことについてそのものズバリな質問がありました。 Why can't C++ be parsed with a LR(1) parser?
C++は オペレーターオーバーロードに関係なく LR(1)クラス構文ではないようですね。
arithmeticae
@marionette-of-u
なるほど。ありがとうございます
Kohei Takahashi
@Flast
人増えてきた!
nyaocat
@nyaocat
めでたい(?)
Cryolite
@Cryolite

初心者質問ですいません!

int main() {
  int *p = nullptr;
  *p = 42;
}

が undefined behavior を起こすかどうかを純粋に規格の文言だけから結論できますでしょうか?

Kohei Takahashi
@Flast

微妙にそれるけど明らかなものとしては、pointer to member typeに関してはn4296 [expr.mptr.oper]/6に

If the second operand is the null pointer to member value (4.11), the behavior is undefined.

ってあるので、これはUB

で、本題の方はちょっと怪しくて、

揚げ足を取るような読み方すると、まずn4296 [dcl.ref]/5に

A reference shall be initialized to refer to a valid object or function. [ Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior.

というのがあって、じゃぁreferって何ってなるとn4296 [expr.unary.op]/1には

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

とあるので、nullptrの位置にvalid objectがないことを示せればなんとかUBに持ち込めそう

Kohei Takahashi
@Flast
n4296 [dcl.ref]/5にUBって書いてあるじゃんって指摘には、これはNoteなので規格の挙動に影響を与えられないっていうのがあって書いてあるのに残念
op->*op[]に関してはそれぞれop.*op*へのequivalenceであることが示されているので割愛
Kohei Takahashi
@Flast
.oO(*がmarkdownに食われるの何とかできないかな...
nyaocat
@nyaocat
規格書さらってみましたけど Flast さんが既に書いてる以上の関係ありそうな文言はみつけられず _(:3 」∠)_
*アスタリスクは 先に \ をいれてやればエスケープできるみたいですね。 *
This message was deleted