C++ 函数模板,不允许某些类型

C++ 函数模板,不允许某些类型,c++,templates,c++11,C++,Templates,C++11,我有一个函数模板,必须是只允许某些类型。我见过其他问题,但他们使用boost和primitve类型。在本例中,没有boost,它是一个用户定义的类 例: 模板 myfunc(T&) { ... } 模板 myfunc(Foo&) { static_assert(false,“不能将myfunc与Foo一起使用”); } 问题是无论我是否使用Foo对象调用myfunc,都会调用static\u assert 我只想在使用Foo调用myfunc时,找到一种停止编译的方法 如何实现此功能?您可以使用

我有一个函数模板,必须是只允许某些类型。我见过其他问题,但他们使用boost和primitve类型。在本例中,没有boost,它是一个用户定义的类

例:

模板
myfunc(T&)
{ ... }
模板
myfunc(Foo&)
{
static_assert(false,“不能将myfunc与Foo一起使用”);
}
问题是无论我是否使用
Foo
对象调用
myfunc
,都会调用
static\u assert

我只想在使用
Foo
调用
myfunc
时,找到一种停止编译的方法

如何实现此功能?

您可以使用
std::is_same
实现此功能:

#include <type_traits>

template<typename T>
return_type myfunc(T&)
{
   static_assert(std::is_same<T, Foo>::value, "You cannot use myfunc with Foo");

   // ...
}
#包括
模板
返回类型myfunc(T&)
{
static_assert(std::is_same::value,“不能将myfunc与Foo一起使用”);
// ...
}

返回类型为
R
,表示:

#include <type_traits>

template <typename T>
typename std::enable_if<!std::is_same<T, Foo>::value, R>::type my_func(T &)
{
    // ...
}
#包括
模板
typename std::enable_if::value,R>::键入my_func(T&)
{
// ...
}
如果您真的不想使用标准库,您可以自己编写特性:

template <bool, typename> struct enable_if { };
template <typename T> struct enable_if<true, T> { typedef T type; };

template <typename, typename> struct is_same { static const bool value = false; };
template <typename T> struct is_same<T, T> { static const bool value = true; };
template struct enable_if{};
如果{typedef T type;},则模板结构启用_;
模板结构是相同的{static const bool value=false;};
模板结构是相同的{static const bool value=true;};

您的函数没有返回类型……因为没有要选择的实际重载,所以静态断言更好,因为它会给出更好的错误。@R.MartinhoFernandes,这是不可能知道的。ADL将从《我的函数》的作者做梦都没想到的地方收集资料。不过,我会
std::remove_const
。或者可能
std::decay
it.@Xeo是的,我考虑过了,但决定采用与原始版本相同的行为。我可能会使用
Bare
但是:p什么是
Bare
?一个链接就足够了。@n2liquid@KerrekSB对于这个特定场景,我相信没有区别。但总的来说有一个区别:
std::decay
模拟按值传递时发生的情况<代码>裸条带引用和cv限定符。在大多数情况下,这两者是相同的,但并不总是如此:
std::decay::type
int*
,而
Bare
仍然是
int[3]
。我会选择这里的
Bare
,因为我发现它的意思更接近预期。
template <bool, typename> struct enable_if { };
template <typename T> struct enable_if<true, T> { typedef T type; };

template <typename, typename> struct is_same { static const bool value = false; };
template <typename T> struct is_same<T, T> { static const bool value = true; };