是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?
这是我想写的一个简单例子:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)
所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.
我有以下代码段:
#include <algorithm>
#include <iostream>
int main(int argc, char** argv) {
int x[2][3];
int y[2][3];
using std::swap;
std::cout << noexcept(swap(x, y)) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用GCC 4.9.0打印0.我不明白为什么.
根据标准,有两个重载std::swap:
namespace std {
template<class T> void swap(T& a, T& b) noexcept(
is_nothrow_move_constructible<T>::value &&
is_nothrow_move_assignable<T>::value
);
template<class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
}
Run Code Online (Sandbox Code Playgroud)
在我的理解noexcept中,数组的说明符应该递归地用于多维数组.
为什么不交换多维数组noexcept?
在尝试找到一个仍然表现得很奇怪的最小例子时,我想出了以下内容:
#include <iostream>
template<class T> struct Specialized : std::false_type {};
template<> struct Specialized<int> : …Run Code Online (Sandbox Code Playgroud) 我希望boost::swap在我的环境中创建一个等效的标准头文件,或者不能包括在内.取决于项目许可和其他东西.
我想让部分代码受到保护检测器的保护:
我们考虑一个编译单元.
具体项目,上述潜力包括:
#include <algorithm> // (or <utility> for C++11 projects)
Run Code Online (Sandbox Code Playgroud)
稍后在我的交换实用程序头中包含的项目代码中:
namespace MyCompany
{
template<class T1, class T2>
void swap(T1& left, T2& right)
{
#ifdef _ALGORITHM_ // you get the idea.
std::swap(left, right);
#else
// fallback impl
#endif
}
}
Run Code Online (Sandbox Code Playgroud)
我简化了,因为我们不是在讨论ADL技巧的细节,但它将被包括在内.
这里是我所谈论的参考,但这与这个问题无关:http:
//www.boost.org/doc/libs/1_57_0/boost/core/swap.hpp
所以这个问题是关于,如何检测标准头包含?在_ALGORITHM_后卫出现在Visual Studio中提供的头,但我无处阅读http://www.cplusplus.com/reference/algorithm/,它应该有,我可以检查任何宏.
(最后注意:这个问题有点偏向XY.我真正想要的是检测std::swap函数的存在,而不是标题.)
正如我之前提到的一个问题所显示的那样, 重载解析,模板和继承,将在需要派生到基本转换的重载之前选择模板重载.
但是,有没有办法提供一个后备重载,如果没有其他匹配的东西,它只被选为绝对的最后手段?在这种特殊情况下enable_if可以使用,但不幸的是,这种情况是不可扩展的.
像这样:
// My library has this and has no knowledge of the possible overloads of foo
template<typename T>
void foo(const T &) { /* Do something */ }
// The user of the library provides this:
void foo(const UserBaseType &) { /* Do something */ }
// User calls foo with object derived from UserBaseType:
foo(UserDerivedType());
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我希望调用UserBaseType重载,而不是模板重载.