簡體   English   中英

成員函數參數的類型

[英]Type of member functions arguments

使用C ++ 11我試圖從函數名中獲取函數參數的類型,授予函數簽名是明確的。 最后,我試圖調用函數之前檢查參數是否是我想要的類型。

到目前為止,由於此解決方案,我可以使用非成員函數執行此操作: 將函數參數的參數解壓縮到C ++模板類

我稍微編輯了它以獲得以下類:

template<typename T>
struct FunctionSignatureParser; // unimplemented primary template
template<typename Result, typename...Args>
struct FunctionSignatureParser<Result(Args...)>
{
    using return_type = Result;
    using args_tuple = std::tuple<Args...>;
    template <size_t i> struct arg
    {
        typedef typename std::tuple_element<i, args_tuple>::type type;
    };
};

例如,我可以在編譯時檢查函數的類型:

short square(char x) { // 8-bit integer as input, 16-bit integer as output
    return short(x)*short(x);
}
int main() {
        char answer = 42;
        static_assert(std::is_same<char, FunctionSignatureParser<decltype(square)>::arg<0>::type>::value, "Function 'square' does not use an argument of type 'char'");
        static_assert(std::is_same<short, FunctionSignatureParser<decltype(square)>::return_type>::value, "Function 'square' does not return a value of type 'short'");
        short sqrAnswer = square(answer);
        std::cout << "The square of " << +answer << " is " << +sqrAnswer << std::endl;
        return 0;
}

>>在線代碼與gcc

但是當我想檢查成員函數的類型時,一些編譯器對它不滿意:

struct Temperature
{
    double degrees;
    Temperature add(double value);
};
int main() {
    Temperature t{16};
    double increment{8};
    static_assert(std::is_same<double, FunctionSignatureParser<decltype(t.add)>::arg<0>::type>::value, "Method 'Temperature::add' does not use an argument of type 'double'");
    std::cout << t.degrees << u8" \u00b0C + " << increment << " == " << t.add(increment).degrees << u8" \u00b0C" << std::endl;
    return 0;
}

這是gcc 6.3必須說的:

錯誤:無效使用非靜態成員函數'Temperature Temperature :: add(double)'

>>在線代碼與gcc

這是clang 4.0必須說的:

錯誤:必須調用對非靜態成員函數的引用

>>在線代碼與clang

我嘗試過這些選項,但無濟於事:

decltype(Temperature::add)
decltype(std::declval<Temperature>().add)

decltype非靜態成員函數有什么問題? 由於不評估decltype中的表達式,因此static限定符無關緊要,對吧?

為了記錄,MSVC12在這種情況下取​​得了成功。 但我無法判斷Microsoft編譯器是對還是錯。 (請不要讓這個線程成為編譯器之戰)

此外,如果你有一個不涉及初始方法的參數檢查解決方案,我也是開放的。

您需要另一個模板專門化的成員函數,如下所示:

template<typename ClassType, typename Result, typename...Args>
struct FunctionSignatureParser<Result(ClassType::*)(Args...)>
{
    using return_type = Result;
    using args_tuple = std::tuple<Args...>;
    template <size_t i> struct arg
    {
        typedef typename std::tuple_element<i, args_tuple>::type type;
    };
};

它可以像這樣使用:

    static_assert(std::is_same<double, FunctionSignatureParser<decltype(&Temperature::add)>::arg<0>::type>::value, "Method 'Temperature::add' does not use an argument of type 'double'");

這適用於gcc 7.2,尚未測試過其他編譯器

暫無
暫無

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

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