gpt4 book ai didi

c++ - SFINAE 检测类型是否被定义

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:41:27 25 4
gpt4 key购买 nike

我想在定义特定类型时选择模板的特化。

我仍然不能全神贯注于 SFINAE :(。我可能很接近,也可能完全偏离。我尝试了不同的东西,这是一些东西,我至少希望理解为什么它不起作用(is_complete 基本上是从 here 偷来的):

#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();
}

使用 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();
^

我想我或多或少知道哪里出了问题:foo 不依赖于 T,因此不需要替换来获取 foo 和我得到一个硬错误而不是不是错误。接下来,我尝试使用帮助程序

template <typename T>
struct make_foo_dependent {
using type = foo;
};

并尝试在 enable_if 中直接使用它,而不是直接使用 foo。然而,这只是增加了更多的错误,我没有把它包括在这里,因为我担心这也是在错误的方向上。

如何根据 foo 是否定义来选择要调用的函数?如果未定义 foo,则使用 foo 的代码不应发出硬错误,而只是被编译器忽略。

PS:SFINAE 发生了很多变化,我发现很难找到将自己限制在 C++11 上的资源,C++11 的内容似乎比新标准要复杂一些。

最佳答案

是的,正如你所说,你应该制作test取决于模板参数 T ;并且更好地制作两个重载模板。例如

// 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();
}

然后称它为

test(); // or test<foo>();

LIVE (foo is defined)
LIVE (foo is not defined)

顺便说一句:根据您的意图,我认为 test 的返回类型应该是 typename std::enable_if<is_complete<T>::value,void>::type而不是 std::enable_if<is_complete<foo>::value,void> ;这只是 std::enable_if 的实例化类型本身。

关于c++ - SFINAE 检测类型是否被定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57624408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com