[英]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.h
為Foo
和bar.h
Bar
定義create
函數,因此您必須同時包含兩者。
這不是對if constexpr
的批評,因為它在將相關的通用代碼簡短並集中在一個地方方面非常有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.