Dav*_*ria 15 c++ templates specialization sfinae c++11
我试图根据类模板参数确定调用哪个版本的成员函数.我试过这个:
#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();
}
Run Code Online (Sandbox Code Playgroud)
我认为这是说"如果T是int,则使用第一个MyFunction,如果T不是int,则使用第二个MyFunction,但我得到编译器错误"错误:'struct std :: enable_if'中没有类型名为'type'谁能指出我在这里做错了什么?
Pra*_*ian 17
enable_if
因为模板参数的替换导致错误,并且从重载决策集中删除了替换,并且编译器仅考虑其他可行的重载.
在您的示例中,实例化成员函数时不会发生替换,因为当时T
已知模板参数.实现您正在尝试的最简单的方法是创建一个默认的伪模板参数,T
并使用它来执行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;
}
};
Run Code Online (Sandbox Code Playgroud)
编辑:
正如HostileFork在评论中提到的那样,原始示例留下了用户明确指定成员函数的模板参数并获得不正确结果的可能性.以下内容应防止成员函数的显式特化以进行编译.
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;
}
};
Run Code Online (Sandbox Code Playgroud)
一个简单的解决方案是使用委托来处理私有函数:
template<typename T>
struct Point
{
void MyFunction()
{
worker(static_cast<T*>(nullptr)); //pass null argument of type T*
}
private:
void worker(int*)
{
std::cout << "T is int." << std::endl;
}
template<typename U>
void worker(U*)
{
std::cout << "T is not int." << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
当T
is 时int
,worker
将调用第一个函数,因为static_cast<T*>(0)
结果是 类型int*
。在所有其他情况下,将调用 worker 的模板版本。
归档时间: |
|
查看次数: |
14153 次 |
最近记录: |