[英]SFINAE detect if type is defined
I want to pick a specialization of a template when a certain type is defined. 我想在定义某个类型时选择模板的特化。
I still cannot wrap my head around SFINAE :(. I might be close or I might be completely off. I tried different things and this is something, I at least hope to understand why it does not work ( is_complete
basically stolen from here ): 我仍然无法围绕SFINAE :(。我可能会关闭或者我可能完全关闭。我尝试了不同的东西,这是一些东西,我至少希望理解为什么它不起作用(
is_complete
基本上从这里被盗):
#include <iostream>
#include <type_traits>
template <typename T, class = void>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T,decltype(void(sizeof(T)))> : std::true_type {};
// this should be called if foo is not defined
void test() { std::cout << "test base\n"; }
// forward declare foo
struct foo;
// this should be called if foo is defined
template <typename T>
std::enable_if<is_complete<foo>::value,void> test() {
foo::bar();
}
// this is either defined or not
struct foo{
static void bar() { std::cout << "foo bar\n"; }
};
int main(){
test();
}
With gcc 4.8 ( -std=c++11
) i get : 使用gcc 4.8(
-std=c++11
)我得到:
if_type_defined.cpp: In instantiation of ‘struct is_complete<foo>’:
if_type_defined.cpp:16:32: required from here
if_type_defined.cpp:8:42: error: invalid application of ‘sizeof’ to incomplete type ‘foo’
struct is_complete<T,decltype(void(sizeof(T)))> : std::true_type {};
^
if_type_defined.cpp:8:42: error: invalid application of ‘sizeof’ to incomplete type ‘foo’
if_type_defined.cpp: In function ‘std::enable_if<true, void> test()’:
if_type_defined.cpp:17:3: error: incomplete type ‘foo’ used in nested name specifier
foo::bar();
^
I think I know more or less what is wrong: foo
does not depend on T
, hence no substitution needed to get foo
and I get a hard error instead of Not An Error. 我想我或多或少知道错误:
foo
不依赖于T
,因此不需要替换来获取foo
并且我得到一个硬错误而不是Not An Error。 Next I tried to use a helper along the line of 接下来我试着沿着这条线使用一个帮手
template <typename T>
struct make_foo_dependent {
using type = foo;
};
and tried to use that inside the enable_if
instead of foo
directly. 并尝试直接在
enable_if
而不是foo
使用它。 However, this just added more errors and I didnt include it here, because I am afraid this is also going in the wrong direction. 然而,这只是增加了更多错误,我没有把它包含在这里,因为我担心这也是错误的方向。
How can I choose what function to call depending on whether foo
is defined? 如何根据是否定义了
foo
来选择要调用的函数? If foo
is not defined, the code using foo
should not issue a hard error, but simply be ignored by the compiler. 如果未定义
foo
,则使用foo
的代码不应发出硬错误,而是由编译器忽略。
PS: Lots has changed with respect to SFINAE, and I find it hard to find ressources that restrict themself to C++11, where things seem to be a bit more hairy than in newer standards. PS:关于SFINAE的情况已经发生了很大变化,我发现很难找到限制自己使用C ++ 11的资源,在这些情况下,事情似乎比新标准更加毛茸茸。
Yes, as you said, you should make test
depending on the template parameter T
; 是的,正如您所说,您应该根据模板参数
T
进行test
; and better making both the overloads template. 并且更好地制作两个重载模板。 eg
例如
// this should be called if foo is not defined
template <typename T = foo>
typename std::enable_if<!is_complete<T>::value,void>::type test() { std::cout << "test base\n"; }
// this should be called if foo is defined
template <typename T = foo>
typename std::enable_if<is_complete<T>::value,void>::type test() {
T::bar();
}
then call it as 然后称之为
test(); // or test<foo>();
LIVE (foo is defined) LIVE(foo已定义)
LIVE (foo is not defined) LIVE(foo未定义)
BTW: From your intent, I think the return type of test
should be typename std::enable_if<is_complete<T>::value,void>::type
instead of std::enable_if<is_complete<foo>::value,void>
; BTW:从你的意图来看,我认为
test
的返回类型应该是typename std::enable_if<is_complete<T>::value,void>::type
而不是std::enable_if<is_complete<foo>::value,void>
; which is just the type of an instantiation of std::enable_if
itself. 这只是
std::enable_if
本身的实例化类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.