我想尝试一个简单的例子来了解如何使用std::enable_if.在我读完这个答案之后,我认为想出一个简单的例子应该不会太难.我想用来std::enable_if在两个成员函数之间进行选择,并且只允许使用其中一个成员函数.
不幸的是,下面的代码不能用gcc 4.7进行编译,经过数小时和数小时的尝试后我会问你们我的错误是什么.
#include <utility>
#include <iostream>
template< class T >
class Y {
public:
template < typename = typename std::enable_if< true >::type >
T foo() {
return 10;
}
template < typename = typename std::enable_if< false >::type >
T foo() {
return 10;
}
};
int main() {
Y< double > y;
std::cout << y.foo() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
gcc报告以下问题:
% LANG=C make CXXFLAGS="-std=c++0x" enable_if
g++ -std=c++0x enable_if.cpp -o enable_if
enable_if.cpp:12:65: error: `type' in …Run Code Online (Sandbox Code Playgroud) 我知道这个问题提到了Boost的"静态警告",但我想再问一次,具体来说,我是如何实现一个static_warning操作方式类似static_assert但只在编译时发出警告而不是中止编译错误.
我想要类似于Alexandrescu关于在C++之前的11天中静态断言的提议,它在某种程度上设法打印了一些有用的上下文信息作为错误的一部分.
可以接受要求用户启用某些标准编译器警告以使此构造工作(可能是"无效指针转换"或"打破严格别名规则") - 任何警告应该是正常编译的一部分,无论如何都可以使用.
简而言之,我想static_warning(false, "Hello world");创建一个编译器警告,它应该以某种方式在警告消息中包含字符串"hello world".这是可能的,比如在GCC和MSVC,以及如何?
我很乐意为任何特别聪明的解决方案提供小额奖励.
作为一点解释:我在考虑这个问题时得到了一个想法:静态警告将是一种有用的方法来跟踪复杂模板特化的编译时过程,否则这些过程很难调试.静态警告可以用作编译器发出"我现在正在编译代码的这一部分"的简单信标.
更新.理想情况下,警告将在以下设置中触发:
template <typename T> struct Foo
{
static_warning(std::is_pointer<T>::value, "Attempting to use pointer type.");
// ...
};
int main() { Foo<int> a; Foo<int*> b; }
Run Code Online (Sandbox Code Playgroud) 在模板元编程中,可以在返回类型上使用SFINAE 来选择某个模板成员函数,即
template<int N> struct A {
int sum() const noexcept
{ return _sum<N-1>(); }
private:
int _data[N];
template<int I> typename std::enable_if< I,int>::type _sum() const noexcept
{ return _sum<I-1>() + _data[I]; }
template<int I> typename std::enable_if<!I,int>::type _sum() const noexcept
{ return _data[I]; }
};
Run Code Online (Sandbox Code Playgroud)
但是,这对构造函数不起作用.假设,我想声明构造函数
template<int N> struct A {
/* ... */
template<int otherN>
explicit(A<otherN> const&); // only sensible if otherN >= N
};
Run Code Online (Sandbox Code Playgroud)
但不允许这样做otherN < N.
那么,SFINAE可以在这里使用吗?我只对允许自动模板参数扣除的解决方案感兴趣
A<4> a4{};
A<5> a5{};
A<6> …Run Code Online (Sandbox Code Playgroud)