gpt4 book ai didi

c++ - std::string 的 type_traits 段错误

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

Using SFINAE to check for global operator<<? 收集信息和 templates, decltype and non-classtypes ,我得到了以下代码:

http://ideone.com/sEQc87

基本上,我将两个问题的代码结合起来,如果它有 ostream 声明,则调用 print 函数,否则调用 to_string 方法。

摘自问题 1

namespace has_insertion_operator_impl {
typedef char no;
typedef char yes[2];

struct any_t {
template<typename T> any_t( T const& );
};

no operator<<( std::ostream const&, any_t const& );

yes& test( std::ostream& );
no test( no );

template<typename T>
struct has_insertion_operator {
static std::ostream &s;
static T const &t;
static bool const value = sizeof( test(s << t) ) == sizeof( yes );
};
}

template<typename T>
struct has_insertion_operator :
has_insertion_operator_impl::has_insertion_operator<T> {
};

摘自问题 2

template <typename T>
typename std::enable_if<has_insertion_operator<T>::value, T>::type
print(T obj) {
std::cout << "from print()" << std::endl;
}

template <typename T>
typename std::enable_if<!has_insertion_operator<T>::value, T>::type
print(T obj) {
std::cout << obj.to_string() << std::endl;
}

然后我的类是这样的:

struct Foo
{
public:
friend std::ostream& operator<<(std::ostream & os, Foo const& foo);
};

struct Bar
{
public:
std::string to_string() const
{
return "from to_string()";
}
};

测试输出:

int main()
{
print<Foo>(Foo());
print<Bar>(Bar());

//print<Bar>(Foo()); doesn't compile
//print<Foo>(Bar()); doesn't compile

print(Foo());
print(Bar());

print(42);
print('a');
//print(std::string("Hi")); seg-fault
//print("Hey");
//print({1, 2, 3}); doesn't compile
return 0;
}

print(std::string("Hi")); 行段错误。谁能告诉我为什么?

最佳答案

你的两个函数 print() 都应该返回一些东西,但什么都不返回(不像你链接的问答中的版本)。根据 C++11 标准的第 6.6.3/2 段,这是未定义的行为。

如果 print() 不应该返回任何东西,让它返回 void,并将 SFINAE 约束放在模板参数列表中:

template <typename T,
typename std::enable_if<
has_insertion_operator<T>::value, T>::type* = nullptr>
void print(T obj) {
std::cout << "from print()" << std::endl;
}

template <typename T,
typename std::enable_if<
!has_insertion_operator<T>::value, T>::type* = nullptr>
void print(T obj) {
std::cout << obj.to_string() << std::endl;
}

这是一个live example包含上述更改。

如果您正在使用 C++03 并且无法为函数模板参数指定默认参数,只需避免将类型指定为 std::enable_if 的第二个模板参数,或指定 无效:

template <typename T>
typename std::enable_if<has_insertion_operator<T>::value>::type
print(T obj) {
std::cout << "from print()" << std::endl;
}

template <typename T>
typename std::enable_if<!has_insertion_operator<T>::value>::type
print(T obj) {
std::cout << obj.to_string() << std::endl;
}

关于c++ - std::string 的 type_traits 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16528825/

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