【发布时间】:2014-04-01 15:03:22
【问题描述】:
我正在尝试为两种不同类型的类专门化一个成员函数模板,如下所示:
#include <iostream>
#include <boost/utility/enable_if.hpp>
struct Wibble
{
static const bool CAN_WIBBLE = true;
};
struct Wobble
{
static const bool CAN_WIBBLE = false;
};
struct Foo
{
//template<typename T> // Why isn't this declaration sufficient?
//void doStuff();
template<typename T>
typename boost::enable_if_c<T::CAN_WIBBLE,void>::type
doStuff();
template<typename T>
typename boost::enable_if_c<!T::CAN_WIBBLE,void>::type
doStuff();
};
template<typename T>
typename boost::enable_if_c<T::CAN_WIBBLE,void>::type
Foo::doStuff()
{
std::cout << "wibble ..." << std::endl;
}
template<typename T>
typename boost::enable_if_c<!T::CAN_WIBBLE,void>::type
Foo::doStuff()
{
std::cout << "I can't wibble ..." << std::endl;
}
int main()
{
Foo f;
f.doStuff<Wibble>();
f.doStuff<Wobble>();
}
而 GCC 4.8.2 编译代码,VS .NET 2008 吐出错误消息:
error C2244: 'Foo::doStuff' : unable to match function definition to an existing declaration
definition
'boost::enable_if_c<!T::CAN_WIBBLE,void>::type Foo::doStuff(void)'
existing declarations
'boost::enable_if_c<!T::CAN_WIBBLE,void>::type Foo::doStuff(void)'
'boost::enable_if_c<T::CAN_WIBBLE,void>::type Foo::doStuff(void)'
【问题讨论】:
-
我会把它写下来,因为 MSVC++ 逻辑无法处理没有参数和明确指定参数的函数重载(我隐约记得远程相关案例也有一些问题)。当我想要参数推导时,我只会使用重载的函数模板; Jarod42 建议的标签调度是这里的首选方法。
-
gcc 是否在严格的 C++98 模式下编译它(
-std=c++98)?在 C++11 和 MSVC++ 15.0 (MSVS 9.0 (2008)) 中规则有所放宽,而不是 C++11。 -
@Jan,我没有使用 C++11。如果方法是内联的,VS 也会编译它们。
-
我知道您没有使用 C++11,但我不确定 gcc 是否接受默认模式下 C++98 中不允许的内容。这就是我询问严格模式的原因。
-
@Jan 代码使用严格的 C++98 标志在 gcc 4.8.2 中编译,
-std=c++98
标签: c++ templates boost sfinae enable-if