2

C++ では、テンプレート クラスのインスタンスではなく、テンプレート クラスを参照するテンプレート引数を使用できます。たとえば、fun以下の関数。

同時に、クラス定義内でテンプレート引数を省略できる機能があります。たとえば、 の定義では、 を含意するtemplate<class T> class Aと言うことができます。AA<T>

両方のルールが潜在的にあいまいさを生み出す可能性があるケースを見つけました。さらに、あいまいさを解決することはできません。これは MWE であり、 の定義では、としてではなくテンプレート クラスとしてtemplate<class T> class B参照する必要があります。BB<T>

template <template<class> class Y, class T>
auto fun(){return Y<T>{};} // fun can be used with a *template* class

template<class T>
struct A{
    friend void f(A a){} //A here is implicitly A<T>, ok 
};

template<class T>
struct B{
    friend void g(B b){
        fun<A, void>(); // here A is a template class, ok
        fun<B, void>(); // error: no matching function for call to 'fun' because the compiler sees B<T>, not B
    } //A here is implicitly A<T>, 
};

int main(){
    A<void> a{};
    B<void> b{};
    g(b);
}

(関数gはクラス内で定義したいフレンド関数であるため、これを行う必要があります。)

Clang 3.5 では上記のエラーが発生しますが、GCC 4.9.2 では問題ありません。最悪の部分は、追加の仕様を作成してあいまいさを解決できないことです。

たとえば、私は試しました:

    fun<struct B, void>();

    fun<template<class> struct B, void>();

それでも同じエラーが発生します。

テンプレートクラスでBはないclang(または問題のあるコンパイラ)に伝える方法はありますか?B<T>B

(例を簡略化するためにいくつかの C++11 構文を使用しましたが、問題は C++98 にも当てはまります。正しい命名規則を使用していない場合は、修正するか、お知らせください。)

4

0 に答える 0