問題描述
我正在嘗試根據類模板參數確定調用哪個版本的成員函數.我試過這個:
I am trying to determine which version of a member function gets called based on the class template parameter. I have tried this:
#include <iostream>
#include <type_traits>
template<typename T>
struct Point
{
void MyFunction(typename std::enable_if<std::is_same<T, int>::value, T >::type* = 0)
{
std::cout << "T is int." << std::endl;
}
void MyFunction(typename std::enable_if<!std::is_same<T, int>::value, float >::type* = 0)
{
std::cout << "T is not int." << std::endl;
}
};
int main()
{
Point<int> intPoint;
intPoint.MyFunction();
Point<float> floatPoint;
floatPoint.MyFunction();
}
我認為這是說如果 T 是 int,則使用第一個 MyFunction,如果 T 不是 int,則使用第二個 MyFunction,但是我收到編譯器錯誤,說錯誤:'struct std:: 中沒有名為'type'的類型:enable_if'".誰能指出我在這里做錯了什么?
which I thought is saying "use the first MyFunction if T is int, and use the second MyFunction if T is not int, but I get compiler errors saying "error: no type named ‘type’ in ‘struct std::enable_if’". Can anyone point out what I am doing wrong here?
推薦答案
enable_if
有效,因為 模板參數的替換導致錯誤,因此替換從重載決議集中被刪除,編譯器只考慮其他可行的重載.
enable_if
works because the substitution of a template argument resulted in an error, and so that substitution is dropped from the overload resolution set and only other viable overloads are considered by the compiler.
在您的示例中,實例化成員函數時沒有發生替換,因為模板參數 T
那時已經知道.實現您正在嘗試的最簡單方法是創建一個默認為 T
的虛擬模板參數,并使用它來執行 SFINAE.
In your example, there is no substitution occurring when instantiating the member functions because the template argument T
is already known at that time. The simplest way to achieve what you're attempting is to create a dummy template argument that is defaulted to T
and use that to perform SFINAE.
template<typename T>
struct Point
{
template<typename U = T>
typename std::enable_if<std::is_same<U, int>::value>::type
MyFunction()
{
std::cout << "T is int." << std::endl;
}
template<typename U = T>
typename std::enable_if<std::is_same<U, float>::value>::type
MyFunction()
{
std::cout << "T is not int." << std::endl;
}
};
<小時>
正如 HostileFork 在評論中提到的,原始示例留下了用戶為成員函數明確指定模板參數并得到錯誤結果的可能性.以下應防止編譯成員函數的顯式特化.
As HostileFork mentions in the comments, the original example leaves the possibility of the user explicitly specifying template arguments for the member functions and getting an incorrect result. The following should prevent explicit specializations of the member functions from compiling.
template<typename T>
struct Point
{
template<typename... Dummy, typename U = T>
typename std::enable_if<std::is_same<U, int>::value>::type
MyFunction()
{
static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!");
std::cout << "T is int." << std::endl;
}
template<typename... Dummy, typename U = T>
typename std::enable_if<std::is_same<U, float>::value>::type
MyFunction()
{
static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!");
std::cout << "T is not int." << std::endl;
}
};
這篇關于使用不同的 enable_if 條件選擇成員函數的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!