![](/img/trans.png)
[英]Print an address of function in C++, g++/clang++ vs vc++ , who is right?
[英]C++ friend function template overloading and SFINAE different behaviors in clang++, g++, vc++ (C++14 mode)
因此,以下代碼在clang ++(3.8.0)下構建並運行成功,但在g ++(6.3.0)和vc ++(19.10.24903.0)下都失敗了。 g ++和vc ++都抱怨重新定義operator &&。
有誰知道哪個編譯器有問題。 對於無法編譯代碼的編譯器,編譯錯誤的解決方法是什么?
#include <functional>
#include <iostream>
template <typename T>
struct awaitable
{
friend awaitable<void> operator&&(awaitable a1, awaitable a2)
{
std::cout << "operator&&(awaitable a1, awaitable a2) - T: " << typeid(T).name() << std::endl;
return awaitable<void>{};
}
template <typename U = T, typename std::enable_if<!std::is_same<U, void>::value>::type* = nullptr>
friend awaitable<void> operator&&(awaitable<void> a1, awaitable<U> a2)
{
std::cout << "operator&&(awaitable<void> a1, awaitable<U> a2) - U: " << typeid(T).name() << std::endl;
return awaitable<void>{};
}
template <typename U = T, typename std::enable_if<!std::is_same<U, void>::value>::type* = nullptr>
friend awaitable<void> operator&&(awaitable<U> a1, awaitable<void> a2)
{
std::cout << "operator&&(awaitable<U> a1, awaitable<void> a2) - U: " << typeid(T).name() << std::endl;
return awaitable<void>{};
}
};
int main(int argc, const char * argv[])
{
awaitable<int> a1, a2, a3, a4;
auto ar = a1 && (a1 && a2) && (a2 && a3) && a4;
}
clang ++: http : //coliru.stacked-crooked.com/a/cb01926bbcacdfb0
g ++: http : //coliru.stacked-crooked.com/a/73d17a5ae26f22eb
vc ++: http : //webcompiler.cloudapp.net/
SFINAE在模板實例化級別工作,即在struct awaitable<T>
,而不是在模板的單個成員級別。 awaitable<void>
是一個有效的實例化,因此它實例化了該類的所有3個成員的聲明,復制了后者2。
並不是兩個定義相互沖突 - 每個定義都與自身沖突( 例子 )( 更多細節 )。
解決方法1
定義類外的幫助程序操作符(已授予,與您擁有的不完全相同 - 這些將成為模板的任何實例的朋友)
#include <functional>
#include <iostream>
template <typename T>
struct awaitable
{
friend awaitable<void> operator&&(awaitable a1, awaitable a2)
{
std::cout << "operator&&(awaitable a1, awaitable a2) - T: " << typeid(T).name() << std::endl;
return {};
}
template<typename U>
friend std::enable_if_t<!std::is_void<U>::value, awaitable<void>> operator&&(awaitable<void> a1, awaitable<U> a2);
template<typename U>
friend std::enable_if_t<!std::is_void<U>::value, awaitable<void>> operator&&(awaitable<U> a1, awaitable<void> a2);
};
template<typename U>
std::enable_if_t<!std::is_void<U>::value, awaitable<void>> operator&&(awaitable<void> a1, awaitable<U> a2)
{
std::cout << "operator&&(awaitable<void> a1, awaitable<U> a2) - U: " << typeid(U).name() << std::endl;
return {};
}
template<typename U>
std::enable_if_t<!std::is_void<U>::value, awaitable<void>> operator&&(awaitable<U> a1, awaitable<void> a2)
{
std::cout << "operator&&(awaitable<U> a1, awaitable<void> a2) - U: " << typeid(U).name() << std::endl;
return {};
}
int main(int argc, const char * argv[])
{
awaitable<int> a1, a2, a3, a4;
auto ar = a1 && (a1 && a2) && (a2 && a3) && a4;
}
解決方法2
使用無SFINAE可言,而是一個專業化awaitable
。 請注意,專業化是相反的 - 基礎實現是awaitable<void>
的特殊情況,專門化是針對其他一切的。
#include <functional>
#include <iostream>
template <typename T, bool isvoid = std::is_void<T>::value>
struct awaitable
{
friend awaitable<void> operator&&(awaitable a1, awaitable a2)
{
std::cout << "operator&&(awaitable a1, awaitable a2) - void" << std::endl;
return {};
}
};
template <typename T>
struct awaitable<T, false>
{
friend awaitable<void> operator&&(awaitable a1, awaitable a2)
{
std::cout << "operator&&(awaitable a1, awaitable a2) - T: " << typeid(T).name() << std::endl;
return {};
}
friend awaitable<void> operator&&(awaitable<void> a1, awaitable<T> a2)
{
std::cout << "operator&&(awaitable<void> a1, awaitable<T> a2) - U: " << typeid(T).name() << std::endl;
return {};
}
friend awaitable<void> operator&&(awaitable<T> a1, awaitable<void> a2)
{
std::cout << "operator&&(awaitable<T> a1, awaitable<void> a2) - void" << std::endl;
return {};
}
};
int main(int argc, const char * argv[])
{
awaitable<int> a1, a2, a3, a4;
auto ar = a1 && (a1 && a2) && (a2 && a3) && a4;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.