回答編集履歴

4

追加分の説明

2022/09/20 10:50

投稿

SaitoAtsushi
SaitoAtsushi

スコア5444

test CHANGED
@@ -3,3 +3,50 @@
3
3
  ですから `constexpr` 変数の初期化式に (参照であるような) `ar` が (`sizeof` のオペランドなどの評価されない文脈を除いて) 現れること自体が制限にひっかかってしまいます。
4
4
 
5
5
  初期化式の制限として引っかかっているので `foo` の定義の側で出来ることはないと思います。
6
+
7
+ # 追記
8
+
9
+ 質問中の「試したこと」のコードについては説明が簡単です。 「定数ではない」というごく単純なことです。
10
+
11
+ 参照型を通じてメンバ関数を呼出すことは定数式の定義に反しません。 また、オブジェクトが定数でない場合でも `constexpr` 指定されたメンバ関数の定義が適切であれば定数式になります。
12
+
13
+ ```cpp
14
+ #include<array>
15
+ #include<iostream>
16
+
17
+ int main (){
18
+ std::array<int,3> ar{1,2,3};
19
+ constexpr auto foo = ar.size(); // ar は定数ではないがこの式は定数式
20
+ }
21
+ ```
22
+
23
+ このとき `size` は `ar` の内容に依存しないのでコンパイル時に確定できます。
24
+
25
+ 一方で `constexpr` 指定された関数は実引数が定数式であることが要求されます。 コンパイル時に呼び出されるのでコンパイル時にわからないものを渡すことは出来ません。
26
+
27
+ つまり以下のような定義は (たとえ引数を使わなくても) エラーになってしまいます。
28
+
29
+ ```cpp
30
+ constexpr int foo(int x) {
31
+ return 1;
32
+ }
33
+
34
+ int main (){
35
+ int a = 1;
36
+ constexpr auto bar = foo(a);
37
+ }
38
+ ```
39
+
40
+ しかし変数の場所は事前にわかるので参照は定数として機能します。
41
+
42
+ ```cpp
43
+ constexpr int foo(const int& x) {
44
+ return 1;
45
+ }
46
+
47
+ int main (){
48
+ int a = 1;
49
+ constexpr auto bar = foo(a);
50
+ }
51
+ ```
52
+

3

解決策について追記

2022/09/20 09:28

投稿

SaitoAtsushi
SaitoAtsushi

スコア5444

test CHANGED
@@ -1,3 +1,5 @@
1
1
  定数式に存在してはいけないものとして定義されている中に「[参照型の参照](https://timsong-cpp.github.io/cppwp/n4659/expr.const#2.11)」があるのを見つけました。 複雑な例外もあるようですが、質問の例の場合はいずれにもあてはまりません。
2
2
 
3
3
  ですから `constexpr` 変数の初期化式に (参照であるような) `ar` が (`sizeof` のオペランドなどの評価されない文脈を除いて) 現れること自体が制限にひっかかってしまいます。
4
+
5
+ 初期化式の制限として引っかかっているので `foo` の定義の側で出来ることはないと思います。

2

補足条件を追加

2022/09/20 09:23

投稿

SaitoAtsushi
SaitoAtsushi

スコア5444

test CHANGED
@@ -1,3 +1,3 @@
1
1
  定数式に存在してはいけないものとして定義されている中に「[参照型の参照](https://timsong-cpp.github.io/cppwp/n4659/expr.const#2.11)」があるのを見つけました。 複雑な例外もあるようですが、質問の例の場合はいずれにもあてはまりません。
2
2
 
3
- ですから `constexpr` 変数の初期化式に `ar` が (`sizeof` のオペランドなどの評価されない文脈を除いて) 現れること自体が制限にひっかかってしまいます。
3
+ ですから `constexpr` 変数の初期化式に (参照であるような) `ar` が (`sizeof` のオペランドなどの評価されない文脈を除いて) 現れること自体が制限にひっかかってしまいます。

1

要約を追加

2022/09/20 09:19

投稿

SaitoAtsushi
SaitoAtsushi

スコア5444

test CHANGED
@@ -1,2 +1,3 @@
1
1
  定数式に存在してはいけないものとして定義されている中に「[参照型の参照](https://timsong-cpp.github.io/cppwp/n4659/expr.const#2.11)」があるのを見つけました。 複雑な例外もあるようですが、質問の例の場合はいずれにもあてはまりません。
2
2
 
3
+ ですから `constexpr` 変数の初期化式に `ar` が (`sizeof` のオペランドなどの評価されない文脈を除いて) 現れること自体が制限にひっかかってしまいます。