[英]Implicit conversion between template type
我創建了兩種類型: bool_t
和number_t
,我想將它們轉換為另一種(以兩種方式)。 但是,在將bool_t
轉換為number_t
遇到了一些問題。
基本上我想做的是(但它不能編譯):
template<bool v>
struct bool_t {
template<template<int> typename T>
operator T<v ? 1 : 0>() {
return {};
}
};
template<int N>
struct number_t {
template<int n1, int n2>
friend number_t<n1 + n2> operator+(number_t<n1>, number_t<n2>) {
return {};
}
};
int main() {
number_t<0>{} + bool_t<0>{};
}
錯誤是:
prog.cc:19:19: error: invalid operands to binary expression ('number_t<0>' and 'bool_t<0>')
number_t<0>{} + bool_t<0>{};
~~~~~~~~~~~~~ ^ ~~~~~~~~~~~
prog.cc:12:26: note: candidate template ignored: could not match 'number_t' against 'bool_t'
friend number_t<n1 + n2> operator+(number_t<n1>, number_t<n2>) {
^
1 error generated.
如何解決這個問題呢?
嘗試將函數自變量類型與函數自變量類型進行匹配以進行模板自變量推導時,將不考慮用戶定義的轉換。 因此,此問題是此類錯誤的較復雜版本:
template <int> struct X {};
struct Y {
operator X<2> () const { return {}; }
};
template <int N>
void f(X<N>) {}
int main()
{
Y y;
f(y); // Error: Cannot deduce template argument.
}
既然您似乎在按照模板元編程庫的方式進行操作,也許您可以定義一個自定義機制以將庫中的類型“轉換為模板”?
#include <type_traits>
template<bool v>
struct bool_t {
// (Add some appropriate SFINAE.)
template<template<int> typename T>
constexpr T<v ? 1 : 0> convert_template() const {
return {};
}
};
template<typename T, template<int> class TT>
struct type_specializes : std::false_type {};
template<template<int> class TT, int N>
struct type_specializes<TT<N>, TT> : std::true_type {};
template<int N>
struct number_t {
// Allow "conversion" to my own template:
template<template<int> typename T>
constexpr std::enable_if_t<type_specializes<number_t, T>::value, number_t>
convert_template() const { return {}; }
private:
// Used only in decltype; no definition needed.
template<int n1, int n2>
static number_t<n1 + n2> sum_impl(number_t<n1>, number_t<n2>);
template<typename T1, typename T2>
friend auto operator+(T1&& x, T2&& y)
-> decltype(number_t::sum_impl(
x.template convert_template<number_t>(),
y.template convert_template<number_t>()))
{ return {}; }
};
int main() {
number_t<0>{} + bool_t<0>{};
}
如果要允許兩個操作數bool_t
專業化,則operator+
將需要是適當的可見命名空間成員; 您可以根據需要向其中添加更多SFINAE檢查。
您的問題歸結為該語言最多允許一次隱式轉換。
一種解決方案是使一個函數也接受bool_t:
number_t<n1 + n2> operator+(number_t<n1>, bool_t<n2>) {
//return something
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.