为什么默认模板参数只允许在类模板上?为什么我们不能在成员函数模板中定义默认类型?例如:
struct mycclass {
template<class T=int>
void mymember(T* vec) {
// ...
}
};
Run Code Online (Sandbox Code Playgroud)
相反,C++强制只允许在类模板上使用默认模板参数.
考虑以下代码:
#include <iostream>
#include <type_traits>
template <typename T>
struct A {
int val = 0;
template <class = typename std::enable_if<T::value>::type>
A(int n) : val(n) {};
A(...) { }
/* ... */
};
struct YES { constexpr static bool value = true; };
struct NO { constexpr static bool value = false; };
int main() {
A<YES> y(10);
A<NO> n;
std::cout << "YES: " << y.val << std::endl
<< "NO: " << n.val << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我想有选择地使用enable_if为某些类型定义构造函数A :: A(int).对于所有其他类型,都有默认构造函数A :: A(...),当替换失败时,它应该是编译器的默认情况.然而这对我来说有意义编译器(gcc版本4.9.0 …
为什么这不能用gcc48和clang32编译?
#include <type_traits>
template <int N>
struct S {
template<class T>
typename std::enable_if<N==1, int>::type
f(T t) {return 1;};
template<class T>
typename std::enable_if<N!=1, int>::type
f(T t) {return 2;};
};
int main() {
S<1> s1;
return s1.f(99);
}
Run Code Online (Sandbox Code Playgroud)
GCC错误:
/home/lvv/p/sto/test/t.cc:12:2: error: no type named ‘type’ in ‘struct enable_if<false, int>’
f(T t) {return 2;};
^
Run Code Online (Sandbox Code Playgroud)
CLANG错误:
/home/lvv/p/sto/test/t.cc:11:26: error: no type named 'type' in 'std::enable_if<false, int>'; 'enable_if' cannot be used to
disable this declaration
typename std::enable_if<N!=1, int>::type
^~~~
/home/lvv/p/sto/test/t.cc:16:7: note: in instantiation of template …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) 在C++ 0x中,简化了SFINAE规则,使得在演绎的"直接上下文"中出现的任何无效表达式或类型不会导致编译器错误,而是导致演绎失败(SFINAE).
我的问题是:
如果我采用重载函数的地址并且无法解决,那么在演绎的直接上下文中是否会失败?
(如果它无法解决,那么它是一个硬错误还是SFINAE)?
以下是一些示例代码:
struct X
{
// template<class T> T* foo(T,T); // lets not over-complicate things for now
void foo(char);
void foo(int);
};
template<class U> struct S
{
template<int> struct size_map
{ typedef int type; };
// here is where we take the address of a possibly overloaded function
template<class T> void f(T,
typename size_map<sizeof(&U::foo)>::type* = 0);
void f(...);
};
int main()
{
S<X> s;
// should this cause a compiler error because 'auto T = &X::foo' …Run Code Online (Sandbox Code Playgroud) #include <type_traits>
struct A{};
struct B{};
template <typename T>
struct Foo
{
typename std::enable_if<std::is_same<T, A>::value>::type
bar()
{}
typename std::enable_if<std::is_same<T, B>::value>::type
bar()
{}
};
Run Code Online (Sandbox Code Playgroud)
错误信息:
14:5: error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded 10:5:
error: with 'typename std::enable_if<std::is_same<T, A>::value>::type Foo<T>::bar()'
Run Code Online (Sandbox Code Playgroud)
来源cpp.sh.我以为两者typename std::enable_if<std::is_same<T,?>::value>::type在同一时间都无效.
编辑
对于后人来说,这是基于@ KerrekSB答案的编辑 - SFINAE仅适用于推导出的模板参数
#include <type_traits>
struct A{};
struct B{};
template<typename T>
struct Foo
{
template<typename U = T>
typename std::enable_if<std::is_same<U,A>::value>::type
bar()
{
}
template<typename U = T>
typename std::enable_if<std::is_same<U,B>::value>::type
bar()
{
} …Run Code Online (Sandbox Code Playgroud) 我试图根据类模板参数确定调用哪个版本的成员函数.我试过这个:
#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'谁能指出我在这里做错了什么?
在代码中:
template<class T>
struct is_builtin
{
enum {value = 0};
};
template<>
struct is_builtin<char>
{
enum {value = 1};
};
template<>
struct is_builtin<int>
{
enum {value = 1};
};
template<>
struct is_builtin<double>
{
enum {value = 1};
};
template<class T>
struct My
{
typename enable_if<is_builtin<T>::value,void>::type f(T arg)
{
std::cout << "Built-in as a param.\n";
}
typename enable_if<!is_builtin<T>::value,void>::type f(T arg)
{
std::cout << "Non - built-in as a param.\n";
}
};
struct A
{
};
int main()
{
A a;
My<int> …Run Code Online (Sandbox Code Playgroud) template<typename T>
struct A
{
A<T> operator%( const T& x);
};
template<typename T>
A<T> A<T>::operator%( const T& x ) { ... }
Run Code Online (Sandbox Code Playgroud)
如何使用enable_if为任何浮点类型(is_floating_point)进行以下特化?
template<>
A<float> A<float>::operator%( const float& x ) { ... }
Run Code Online (Sandbox Code Playgroud)
编辑:这是我提出的答案,与下面发布的答案不同......
template<typename T>
struct A
{
T x;
A( const T& _x ) : x(_x) {}
template<typename Q>
typename std::enable_if<std::is_same<Q, T>::value && std::is_floating_point<Q>::value, A<T> >::type operator% ( const Q& right ) const
{
return A<T>(fmod(x, right));
}
template<typename Q>
typename std::enable_if<std::is_convertible<Q, T>::value && !std::is_floating_point<Q>::value, A<T> >::type operator% …Run Code Online (Sandbox Code Playgroud) 我正在创建一个非常小的C++项目,我想根据自己的需要创建一个简单的矢量类.该std::vector模板类不会做.当向量类由chars(即vector<char>)组成时,我希望它能够与a进行比较std::string.经过一番乱搞之后,我编写的代码既可以编译也可以执行我想要的操作.见下文:
#include <string>
#include <stdlib.h>
#include <string.h>
template <typename ElementType>
class WorkingSimpleVector {
public:
const ElementType * elements_;
size_t count_;
// ...
template <typename ET = ElementType>
inline typename std::enable_if<std::is_same<ET, char>::value && std::is_same<ElementType, char>::value, bool>::type
operator==(const std::string & other) const {
if (count_ == other.length())
{
return memcmp(elements_, other.c_str(), other.length()) == 0;
}
return false;
}
};
template <typename ElementType>
class NotWorkingSimpleVector {
public:
const ElementType * elements_;
size_t count_;
// ... …Run Code Online (Sandbox Code Playgroud)