C++ 函数内部具有模板类型的不同操作不例外

C++ 函数内部具有模板类型的不同操作不例外,c++,c++11,stl,noexcept,C++,C++11,Stl,Noexcept,我想编写一个模板函数foo,它对类型T执行一些操作,在这个函数中,类型T的值可以是: 抄袭 指派 与运算符求和+ 因此,我需要为这个函数指定noexcept,并带有上面提到的限制 这是我的代码,但它不能正常工作: template<class T> void foo() noexcept(noexcept(std::declval<T>() + std::declval<T>()) && std::is_copy_construc

我想编写一个模板函数foo,它对类型T执行一些操作,在这个函数中,类型T的值可以是:

  • 抄袭
  • 指派
  • 与运算符求和+
因此,我需要为这个函数指定noexcept,并带有上面提到的限制

这是我的代码,但它不能正常工作:

template<class T>
void foo() 
    noexcept(noexcept(std::declval<T>() + std::declval<T>()) && std::is_copy_constructible<T>::value && std::is_assignable<T, T>::value)
{}

bool b1 = noexcept(foo<int>()); // false, but should return true
bool b2 = noexcept(foo<std::string>()); // false
模板
void foo()
noexcept(noexcept(std::declval()+std::declval())&&std::is\u copy\u constructible::value&&std::is\u assignable::value)
{}
bool b1=noexcept(foo());//false,但应该返回true
boolb2=noexcept(foo());//错误的

我应该怎么做才能使它正常工作?

noexcept(foo())
为false,因为
std::is_assignable::value
为false,例如,您无法写入
1=1
。您可能想做的是使用
std::is\u assignable

问题在于您的
std::is\u assignable
(即
false
)。通常情况下,您不能分配给
int
,只能分配给
int&
(即,l值引用,这意味着您正在修改的实际对象的存在)。如果没有引用限定符,r值也必须是可赋值的(例如语句
1=1
必须是有效的)


因此,在
std::is_assignable
表达式中将
T
更改为
T&

您尝试使用
noexcept()
检查
T运算符+(T,T)
的存在,但这只会检测
noexcept运算符+
。在我看来,我们可以做得更好

namespace detail
{
    template<class>
    struct sfinae_true : std::true_type{};

    template<class T>
    static auto can_add(int) -> sfinae_true<decltype(std::declval<T>() + std::declval<T>())>;

    template<class>
    static auto can_add(long) -> std::false_type;
}
template<class T>
struct can_add : decltype(detail::can_add<T>(0))
{};

然后,您可以定义:

template<class T>
struct is_foo_compatible : std::conjunction<
    can_add<T>,
    std::is_copy_constructible<T>,
    std::is_assignable<T&, T>
> {};
模板
结构是兼容的:std::conjunction<
你能补充一下吗,
std::是可复制的吗,
std::是可分配的吗
> {};

而且它很有效™.

所以,我需要为这个函数指定noexcept“我看不到因果关系。为什么不简单地使用sfinae?@YSC在这种特定情况下,我不能使用sfinae。只有定义了
operator+(t,t)
noexcept
,它才会起作用。什么?@YSC这只是我试图用这样的运算符+定义这个函数,如果你知道解决这个问题的另一种方法,请写在这里好吧,sfinae,但你说你可以(不允许?)不可以。
template<class T>
struct is_foo_compatible : std::conjunction<
    can_add<T>,
    std::is_copy_constructible<T>,
    std::is_assignable<T&, T>
> {};