簡體   English   中英

使用 std::is_same_v 而不是重載或特化有任何潛在問題嗎?

[英]Any potential problem with using std::is_same_v rather than overload or specialization?

例如,我有這個:

// Code A
int create_int() { return 42; }
double create_double() { return 3.14; }
std::string create_string() { return {"Hi"}; }

現在讓我們假設將這些create放在一起是有意義的,所以我重寫了代碼:

// Code B
template <typename T> T create();
template <> int create<int>() { return 42; }
template <> double create<double>() { return 3.14; }
template <> std::string create<std::string>() { return {"Hi"}; }

甚至:

// Code C
#include <type_traits>

template <typename T> T create()
{
    if constexpr (std::is_same_v<T, int>)
    {
        return 42;
    }
    else if constexpr (std::is_same_v<T, double>)
    {
        return 3.14;
    }
    else if constexpr (std::is_same_v<T, std::string>)
    {
        return {"Hi"};
    }
    else
    {
        // static_assert(false);
        return static_cast<T>(0);
    }
}

我想知道這些代碼之間有什么區別,或者只是代碼風格。

這些之間存在語義差異。 您不能在此示例中的通用算法中使用Code A函數:

template <class T>
T generic_function() {
    return create<T>();
}

因此,我更喜歡代碼 B 而不是代碼 A。

如果您需要在通用算法中采用不同的路線,則 constexpr if 很有用。 它使您免於創建重載的輔助函數或更糟糕的構造。

一個例子是對void采取不同的路線而不是其他數據類型,因為您不能將void作為參數傳遞給函數。 假設您使用一個函數並希望將std::promise的值設置為結果。 此函數可能不會返回值,但您仍希望執行該函數。 在這種情況下, constexpr if將使您免於大量頭痛和模板元編程。

template <class Fn>
void my_function(Fn fn) {
    std::promise<decltype(fn())> promise;

    if constexpr(!std::is_same_v<void, decltype(fn())>) {
        promise.set_value(fn());
    } else {
        fn();
        promise.set_value();
    }
}

這取決於您的用例。 if constexpr僅限於函數范圍,則意味着您無法在foo.hFoobar.h Bar定義create函數,因此您必須同時包含兩者。

這不是對if constexpr的批評,因為它在將相關的通用代碼簡短並集中在一個地方方面非常有用。

暫無
暫無

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

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