38

C++1y/C++14 N3690 によると、変数テンプレートの特殊化の型は、プライマリ テンプレートの型と同じである必要がありますか?

template<int x>
char y = f(x);

template<>
double y<42> = g();

もしそうなら、どういうわけかプライマリを未定義のままにすることは可能ですか?

template<int x>
???? y = ???; // undefined

template<>
double y<42> = g();

これはドラフトのどこでカバーされていますか?

クラス テンプレートの同等の機能は次のようになります。

template<int x>
struct S
{
    static char y;
};

template<>
struct S<42>
{
    static double y;
};

template<int x>
struct S; // undefined

template<>
struct S<42>
{
    static double y;
};
4

5 に答える 5

35

変数テンプレートの特殊化の型は、プライマリ テンプレートの型と同じでなければなりませんか?

いいえ、変数テンプレートの明示的な (または部分的な) 特殊化は、暗黙的なインスタンス化によって暗示される型とは異なる型を指定できます。Clang の機能を実装する際に、仕様にはこの場合の型の一致を要求するルールがないことを発見し、この問題を C++ コア ワーキング グループに持ち込んで、この省略が意図的なものであることが確認されました。

どういうわけかプライマリを未定義のままにすることは可能ですか?

型を指定せずにプライマリ変数テンプレートを宣言することはできません。そのようなことを可能にする構文はありません。

これはドラフトのどこでカバーされていますか?

これらは両方とも省略されています。型が一致することを要求する規則はなく、型のない変数テンプレートを宣言するための構文もありません。したがって、標準の特定の部分を指して「ここにルールがない」とは言えません。

C++ 標準委員会のリフレクターにアクセスできる場合は、core-23901 で始まるスレッドを参照して、これに関する議論を行ってください。

于 2014-01-23T20:52:01.433 に答える
3

以下は、clang トランクでコンパイルされます-std=c++1y

#include <iostream>

template<int x>
char y = 3;

template<>
double y<42> = 2.5;

char c {y<17>};

double d {y<42>};

したがって、変数テンプレートの特殊化がそのプライマリと同じ型である必要がないか、clang に N3690 のバグのある実装があるかのいずれかです。

于 2013-10-01T05:52:05.603 に答える
1

特殊化の宣言は、そのタイプを含めて、プライマリ テンプレートと正確に一致する必要があることを十分に期待しています。これは、変数テンプレートにとって新しいことではありません。標準の詳細をまだ追跡していませんが、この詳細がどこで指定されているかを確認しています。

以下のコードは、あなたが望むものと似たようなことをしているようです。つまり、変数の型を開いたままにしておきます。

#include <iostream>

template <int X> struct var_type { typedef int type; };
template <> struct var_type<42> { typedef double type; };

int    f(int x) { return x; }
double g()    { return 3.14; }

template <int X>
typename var_type<X>::type var = f(X);
template <>
typename var_type<42>::type var<42> = g();

int main()
{
    std::cout << "var<17>=" << var<17> << '\n';
    std::cout << "var<42>=" << var<42> << '\n';
}
于 2013-10-01T05:26:25.890 に答える
0

Clang が標準化を目的とした機能を表現していると推測するのは少し危険です。(注:この回答については何も参照していません。)

もちろん、タイプの変更を許可することの副次的な問題は、何らかの方法で参照された後にテンプレートを特殊化できないことです。一方、他のすべての種類のテンプレートでは、カットオフ タイムは ODR で使用されます。何かおかしなことを計画していない限り、これは Clang のバグのように見えます。

型テンプレートを使用して、変数テンプレートの型を宣言できます。

template< typename t >
struct x_type { typedef … type; };

template< typename t >
typename x_type< t >::type x = …;

x_typeは特化しているかもしれません。これは、Clang に現在バグがある可能性を防ぐためのものです。不確定な型のオブジェクトを参照することはできません。C++ はそれをサポートしていません。オブジェクト ODR を参照すると、クラス テンプレートの特殊化が使用されます。

于 2013-10-01T06:26:47.450 に答える