我有一個簡單的功能:
template<class T>
typename std::enable_if_t<std::is_arithmetic_v<T>>
foo(T val) { }
我還想有另一個同名的函式:
template<class T>
void foo(T value) { }
我想用算術型別呼叫第一個函式,為所有其他型別呼叫第二個函式。我的一個想法是將第二個函式更改為:
template<class T>
typename std::enable_if_t<!std::is_arithmetic_v<T>>
foo(T val) { }
但有沒有更好的方法來實作這一目標?
uj5u.com熱心網友回復:
更好、更直觀的方法是使用 C 20 概念。
#include <concepts>
template<class T>
requires std::is_arithmetic_v<T>
void foo(T value) { }
template<class T>
void foo(T value) { }
當您呼叫 時foo(0),由于滿足第一個多載的約束,它將優先于第二個無約束多載。
呼叫時foo("hello"),由于不滿足第一個多載的約束,編譯器會選擇第二個多載。
uj5u.com熱心網友回復:
使用if constexpr:
template<class T>
void foo(T value)
{
if constexpr (std::is_arithmetic_v<T>) {
// ... one implementation
} else {
// ... another implementation
}
}
uj5u.com熱心網友回復:
您可以通過利用多載決議來做到這一點:
template<class T>
typename std::enable_if_t<std::is_arithmetic_v<T>>
foo(T val, int)
{
std::cout << "arithmetic: " << (val val) << '\n';
}
template<typename T>
void foo(const T& val, long)
{
std::cout << "Def: " << val << '\n';
}
template<typename T>
void foo(T&& x)
{
foo(std::forward<T>(x), 0);
}
https://godbolt.org/z/sM1KbT8vE
現在int過載是首選,但如果它因為 SFINAE 而失敗,它會跳轉到long過載。
在簡單的情況下,我更喜歡!std::eneble_if_t方法,但如果您有更多特殊情況,多載決議會更方便。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/358923.html
