簡體   English   中英

靜態成員函數的模板特化;如何?

[英]template specialization for static member functions; howto?

我正在嘗試使用模板特化來實現帶有句柄的模板函數。

以下代碼在gcc中給出了“非命名空間作用域中的顯式特化”:

template <typename T>
static T safeGuiCall(boost::function<T ()> _f)
{
    if (_f.empty())
        throw GuiException("Function pointer empty");
    {
        ThreadGuard g;
        T ret = _f();
        return ret;
    }
}

// template specialization for functions wit no return value
template <>
static void safeGuiCall<void>(boost::function<void ()> _f)
{
    if (_f.empty())
        throw GuiException("Function pointer empty");
    {
        ThreadGuard g;
        _f();
    }
}

我已經嘗試將它移出類(該類沒有模板化)並進入命名空間,但后來我得到錯誤“顯式專門化不能有一個存儲類”。 我已經閱讀了很多關於此的討論,但人們似乎並不同意如何專門化功能模板。 有任何想法嗎?

當您專門化模板化方法時,必須在類括號之外執行此操作:

template <typename X> struct Test {}; // to simulate type dependency

struct X // class declaration: only generic
{
   template <typename T>
   static void f( Test<T> );
};

// template definition:
template <typename T>
void X::f( Test<T> ) {
   std::cout << "generic" << std::endl;
}
template <>
inline void X::f<void>( Test<void> ) {
   std::cout << "specific" << std::endl;
}

int main()
{
   Test<int> ti;
   Test<void> tv;
   X::f( ti ); // prints 'generic'
   X::f( tv ); // prints 'specific'
}

當您將其帶到課外時,必須刪除'static'關鍵字。 類之外的靜態關鍵字具有與您可能想要的不同的特定含義。

template <typename X> struct Test {}; // to simulate type dependency

template <typename T>
void f( Test<T> ) {
   std::cout << "generic" << std::endl;
}
template <>
void f<void>( Test<void> ) {
   std::cout << "specific" << std::endl;
}

int main()
{
   Test<int> ti;
   Test<void> tv;
   f( ti ); // prints 'generic'
   f( tv ); // prints 'specific'
}

這不是你的問題的直接答案,但你可以寫這個

template <typename T>
static T safeGuiCall(boost::function<T ()> _f)
{
        if (_f.empty())
                throw GuiException("Function pointer empty");
        {
                ThreadGuard g;
                return _f();
        }
}

它應該工作,即使_f()返回'void'

編輯:在更一般的情況下,我認為我們應該更喜歡函數重載而不是特化。 以下是一個很好的解釋: http//www.gotw.ca/publications/mill17.htm

您可以像在類之外定義成員函數一樣聲明顯式特化:

class A
{
public:
  template <typename T>
  static void foo () {}
};

template <>
void A::foo<void> ()
{
}

您的問題似乎與boost :: function - 以下專業化工作:

template <typename T>
T safeGuiCall()
{
    return T();
}

template <>
void safeGuiCall<void>()
{
}

int main() {
    int x = safeGuiCall<int>();     // ok
    //int z = safeGuiCall<void>();  // this should & does fail
    safeGuiCall<void>();            // ok
}

我遇到了類似的問題。 如果你看一下原來的帖子,我就把第一個靜態輸入了,但是拿出了第二個,並且BOTH錯誤就消失了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM