簡體   English   中英

模板類成員與非成員模板函數的歧義

[英]Template class member vs. non-member template function ambiguity

我正在開發用於自動/算法區分的僅標頭的庫。 目的是能夠簡單地更改輸入給函數的變量的類型並計算一階和二階導數。 為此,我創建了一個模板類,使程序員可以選擇私有數據成員的存儲類型。 下面是一個帶有令人討厭的操作員重載的代碼段。

template <typename storage_t>
class HyperDual
{
    template <typename T> friend class HyperDual;
    public:
        template <typename T>
        HyperDual<storage_t> operator+(const HyperDual<T>& rhs) const
        {
            HyperDual<storage_t> sum;
            for (size_t i = 0; i < this->values.size(); i++)
                sum.values[i] = this->values[i] + rhs.values[i];
            return sum;
        }
    protected:
        std::vector<storage_t> values;
};

稍后,為了最大限度地提高多功能性,我提供了允許交互的模板功能。

template <typename storage_t, typename T>
HyperDual<storage_t> operator+(const HyperDual<storage_t>& lhs, const T& rhs)
{
    static_assert(std::is_arithmetic<T>::value && !(std::is_same<T, char>::value), "RHS must be numeric");
    return HyperDual<storage_t>(lhs.values[0] + rhs);
}

template <typename storage_t, typename T>
HyperDual<storage_t> operator+(const T& lhs, const HyperDual<storage_t>& rhs)
{
    static_assert(std::is_arithmetic<T>::value && !(std::is_same<T, char>::value), "LHS must be numeric");
    return HyperDual<storage_t>(lhs + rhs.values[0]);
}

我遇到的是編譯器正在嘗試實例化第二個非成員模板函數。

#include "hyperspace.h"

int main()
{
    HyperDual<long double> one(1); // There is an appropriate constructor
    HyperDual<double> two(2);

    one + two;

    return 0;
}

為此,我收到static_assert生成的錯誤“ LHS必須為數字”。 我將如何解決歧義?

使用enable_if_t可以使非成員模板只能在特定上下文中應用?

template <typename storage_t, typename T, typename = enable_if_t<std::is_arithmetic<T>::value && !(std::is_same<T, char>::value)>>
HyperDual<storage_t> operator+(const HyperDual<storage_t>& lhs, const T& rhs)
{
    static_assert(std::is_arithmetic<T>::value && !(std::is_same<T, char>::value), "RHS must be numeric");
    return HyperDual<storage_t>(lhs.values[0] + rhs);
}

static_assert可能在此處重復。

好。 我發現了自己的問題。 歸結為static_assert和std :: enable_if之間的區別

替換模板聲明並刪除static_assert,我實現了等效的功能:

template <typename storage_t, typename T,
          typename = typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, char>::value>::type>
HyperDual<storage_t> operator+(const T& lhs, const HyperDual<storage_t>& rhs)
{
    return HyperDual<storage_t>(lhs + rhs.value());
}

(很小的細節,但rhs.values[0]rhs.value()代替。這與模板問題無關,但與成員訪問有關。

暫無
暫無

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

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