Scott Meyers发表了他的下一本书EC++ 11的内容和状态.他写道,书中的一个项目可能是"避免std::enable_if
功能签名".
std::enable_if
可以用作函数参数,返回类型或类模板或函数模板参数,以有条件地从重载解析中删除函数或类.
在这个问题中,显示了所有三个解决方案
作为功能参数:
template<typename T>
struct Check1
{
template<typename U = T>
U read(typename std::enable_if<
std::is_same<U, int>::value >::type* = 0) { return 42; }
template<typename U = T>
U read(typename std::enable_if<
std::is_same<U, double>::value >::type* = 0) { return 3.14; }
};
Run Code Online (Sandbox Code Playgroud)
作为模板参数:
template<typename T>
struct Check2
{
template<typename U = T, typename std::enable_if<
std::is_same<U, int>::value, int>::type = 0>
U read() { return 42; }
template<typename U = T, …
Run Code Online (Sandbox Code Playgroud) 我正在构建一些输入检查器,需要具有整数和/或双精度的特定函数(例如'isPrime'应该仅适用于整数).
如果我使用enable_if
它作为参数它完美地工作:
template <class T>
class check
{
public:
template< class U = T>
inline static U readVal(typename std::enable_if<std::is_same<U, int>::value >::type* = 0)
{
return BuffCheck.getInt();
}
template< class U = T>
inline static U readVal(typename std::enable_if<std::is_same<U, double>::value >::type* = 0)
{
return BuffCheck.getDouble();
}
};
Run Code Online (Sandbox Code Playgroud)
但如果我将它用作模板参数(如http://en.cppreference.com/w/cpp/types/enable_if所示)
template <class T>
class check
{
public:
template< class U = T, class = typename std::enable_if<std::is_same<U, int>::value>::type >
inline static U readVal()
{
return BuffCheck.getInt();
}
template< class U …
Run Code Online (Sandbox Code Playgroud) 当模板完全专用时,不需要复制成员函数.例如,在以下代码中,foo()
只写入一次.
#include <iostream>
template<int M>
class B
{
public:
void foo();
private:
void header();
};
template<int M>
void
B<M>::foo()
{
// specialized code:
header();
// generic code:
std::cout << "M = " << M << std::endl;
}
template<int M>
void
B<M>::header()
{
std::cout << "general foo()" << std::endl;
}
template<>
void
B<2>::header()
{
std::cout << "special foo()" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但是,对于部分特化,有必要复制类定义和所有成员函数.例如:
#include <iostream>
template<int M, int N>
class A
{
public:
void foo();
private:
void header();
};
template<int …
Run Code Online (Sandbox Code Playgroud) 我想根据它的类模板参数有条件地编译一个类的成员.我有便利功能,只有在某些条件下对编译器有意义,所以我希望编译器跳过它们,如果我能以编程方式确定何时这样.
// T is a mathematical type
template <typename T>
class Foo {
public:
// when zero is not clearly defined
void bar(T a, T b, T zero) {
}
// only makes sense if 0 can be cast to T
// will fail otherwise
void bar(T a, T b) {
bar(a, b, 0);
}
}
Run Code Online (Sandbox Code Playgroud)
实现我想要的最好方法是什么?
我想写 5 个不同的类,每个类都有许多完全相同的成员函数,除了一个,每个类都是特殊的。我可以写这个避免代码重复吗?
问候, 阿列克谢
下面是我的代码的一个非常缩短的版本,它引发了错误:
template_test.cpp:15:35: error: invalid use of incomplete type ‘class impl_prototype<cl, 1>
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
using namespace std;
template <int cl, int dim>
class impl_prototype {
public:
impl_prototype() {}
int f(int x) { return cl + 2 * g(x); }
int g(int x) { return cl + 1 * x;}
};
template <int cl>
int impl_prototype<cl, 1>::g(int x) { return cl + 3 * x; }
int main ()
{
impl_prototype<0, 0> test_0;
impl_prototype<0, 1> test_1;
cout …
Run Code Online (Sandbox Code Playgroud) 我基本上试图做一个模板化专业化中讨论的内容,这个模板专门化来自模板化的类,除了我的TClass有多个模板参数,如下所示:
template < class KEY, class TYPE >
class TClass
{
public:
:
void doSomething(KEY * v);
:
};
template < class KEY, class TYPE >
void TClass<KEY, TYPE>::doSomething(KEY * v)
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是有效的,但我如何为一个模板参数定义一个专门的实现?我尝试添加这个:
template < class TYPE >
void TClass<int, TYPE>::doSomething(int * v)
{
// do something if KEY is int
}
Run Code Online (Sandbox Code Playgroud)
但是编译器抱怨"无法将函数定义与现有声明匹配"(VC2010)用于该方法/函数.
作为旁注:如果我同时专门化两个模板参数,它可以工作:
template < >
void TClass<int, char>::doSomething(int * v)
{
// do something if KEY is int and TYPE …
Run Code Online (Sandbox Code Playgroud)