我想寫一個型別別名模板,對于大多數型別來說,它可以決議為模板引數的常量,就像這樣:
我想寫一個型別別名模板。
template <typename T>
using TypeAlias = const T。
但是對于一個特定的型別,比如說int,它只是簡單地決議為T.
。我試著用std::conditional以及包含型別別名的結構的專業化來做這件事,但在所有情況下,編譯器都無法推斷出型別。 我的問題是:我在下面的例子中做錯了什么? 以及如何正確地做到這一點?
編輯:我正在一個非常大的代碼庫中作業,該代碼庫處理大量的型別,并在 TypeAlias(實際上是一個更復雜的型別,基本上是一個在 const T 上模板化的容器)的定義中為所有型別添加 const。 我正試圖修改這個代碼庫,以接受一個不能為const的新型別,同時做最小的修改。 在所有模板化的函式中明確指定型別,如foo,并不是一個可行的解決方案。 我真正要找的是一種修改 TypeAlias 的方法,而不是其他什么。
示例1:
#include <stdio.h>/span>
#include <type_traits>
template <typename T>
using TypeAlias = typename std::conditional<std::is_same<int, T>:value。
T, typename std::add_const<T>:type>:type。
template <typename T>
void foo(TypeAlias<T> var){
printf("var = %f
", static_cast<double>(var))。
}
int main(int argc, char *argv[]) {
const int a = 1;
const float b = 2;
const double c = 3;
foo(a)。
foo(b);
foo(c)。
return 0。
例子2:
template <typename T>
struct TypeHolder {
using type = const T。
};
template <>
struct TypeHolder<int> {
using type = int;
};
template <typename T>
void foo(typename TypeHolder<T>:type var) {
printf("var = %f
", static_cast<double>(var))。
}
int main(int argc, char *argv[]) {
int a = 1;
const float b = 2;
const double c = 3;
foo(a)。
foo(b);
foo(c)。
return 0。
uj5u.com熱心網友回復:
這里有另一種方法來移除特定型別集合的const,只需添加一個多載并使用SFINAE來根據推匯出的型別是否在集合中進行約束:
#include <iostream>
#include <type_traits>
template <class T,class... Ts>。
inline constexpr bool is_any_v = (... || std::is_same_v<T, Ts>)。
template <class T>
inline constexpr bool int_or_short_v = is_any_v<T, int, short> 。
template <class T>
std::enable_if_t<! int_or_short_v<T>> foo(const T) { std::cout << "const" << std::endl; }
template <class T>
std::enable_if_t<int_or_short_v<T>> foo(T) { std::cout << "非const" << std::endl; }
int main() {
const int a = 1;
const short b = 2;
const float c = 3;
const double d = 4;
foo(a)。
foo(b);
foo(c);
foo(d)。
在C 20中,更容易:
#include <iostream>
#include <concepts>
template <class T,class。Ts>。
concept any_of = (... || std::same_as<T, Ts>)。
void foo(const auto) { std: :cout << "const" << std::endl; }
void foo(any_of< int, short> auto) { std: :cout << "non-const"/span> << std::endl; }
int main() {
const int a = 1;
const short b = 2;
const float c = 3;
const double d = 4;
foo(a)。
foo(b);
foo(c);
foo(d)。
uj5u.com熱心網友回復:
正如評論中提到的,這是一個非教育背景,所以模板型別不會被推匯出來。這實際上是你可以用來強迫呼叫者明確設定模板引數的技巧之一。
你可以做的是使用if constexpr來區分你的兩種(或更多)情況:
void foo_for_int(int x) { /*對ints做一些處理 */ }
template <typename T> foo_for_others(T const x) { /* do something for other types */ }
template <typename T>
void foo(T & & t)
{
if constexpr (std::is_same_v<int, T> )
{
foo_for_int(t); //沒有必要轉發一個int。
}
else[/span
{
foo_for_others(std::forward<T> (t))。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/316126.html
標籤:
下一篇:如何使抽象成為一個模板類的超類?
