2011-05-16 12 views
1

C++コードをWindowsからSolaris(Unix)に移植しようとしています。いくつかのテンプレートコードを変更する必要があります。 SolarisのコンパイラCCを使用していますが、g ++にも同じ問題があります。明示的な特殊化テンプレートクラスメンバー関数戻り値の異なるタイプ

私はコードの特定の部分を持っているいくつかのトラブルがあります。彼らは、次のように簡略化されています

#include <exception> 
#include <cmath> 
#include <string> 
#include <iostream> 

// define the "not implement" error 
class tempException: public std::exception 
{ 
public: 
    virtual const char* what() const throw() 
    { 
     return "not been implemented!"; 
    } 
} nondeferr; 

// the template class 
template <typename T> 
class A 
{ 
public: 
    template <typename Val> 
    Val getValue(T t) { throw nondeferr; } 

    template<> 
    double getValue(T t) { return exp(1.5 * t); } //Specialize the getValue for double type. 
}; 

// test code 
int main() 
{ 
    try 
    { 
     A<int> testA; 

     std::cout << testA.getValue<double>(2) << std::endl; 
     std::cout << testA.getValue<std::string>(2) << std::endl; 
    } 
    catch (tempException& e) 
    { 
     std::cout << e.what() << std::endl; 
    } 

return 0; 
} 

は、UNIXでこのサンプルコードをコンパイルするには、コンパイルエラーは、クラススコープにすることはできません明示的な特殊として出てきます。

ここでgetValue関数は戻り値の型とは異なるため、オーバーロードの方法では変更できません。

何らかの理由で、単純なテンプレート変数Tを持つクラスAを、2つのテンプレート変数Tを持つクラスAに変更し、Valは許可されません。この基本クラスを使用しようとすると、多くの変更が導入されます。

解決策があるかどうか分かりますか?私は現在、getValue関数を削除してgetDoubleValueとして置き換えています...しかし、あまりにも良くありません。それらのため


は興味は、今でクラスAは次のようになります誰:

template <typename T> 
class A 
{ 
public: 
    // the Get Value we want 
    template <typename R> 
    R getValue(T t) { return get_value_impl<R>::apply(*this, t); } 

    // the general get value struct 
    template<typename R, typename = void> 
    struct get_value_impl 
    { 
     static R apply(A a, T t) { throw nondeferr; } 
    }; 

    // partial specialization, which is allowed in std C++ 
    template <typename S> 
    struct get_value_impl<double, S> 
    { 
     static double apply(A a, T t) { return exp(1.5 * t); } 
    }; 
}; 

背後にあるロジックは、標準では許可されていない明示的な特殊です。ただし、部分的な特殊化は許可されています。素晴らしいソリューションのおかげでAnycornにもう一度感謝します。

答えて

3
// the template class 
template <typename T> 
class A { 
    template<> 
    double getValue(T t) { return exp(1.5 * t); } 
}; 

これは標準では許可されていません。

が行います。周囲のクラスを専門にすることなく、メンバ関数を特化することはできません

template <typename T> 
class A { 
    template<class R> 
    R getValue(T t) { return get_value_impl<double>::apply(*this, t); } 
    template<class R, class = void> 
    struct get_value_impl; // specialize this 
}; 
+0

解決していただきありがとうございます。提案した内容をテストコードに適用します。それはうまくいく.... :) – ygao

2

。 Visual Studioではこれを拡張子として使用できます。

関連する問題