模板构造函数的优先级

Priority of template constructor

我有模板 class Foo:

template<class T>
class Foo {
public:
    Foo() = default;
    Foo(const Foo&) = default;
    Foo(Foo&&) = default;
    Foo& operator=(Foo&&) = default;
    Foo& operator=(const Foo&) = default;

    template<class U, typename = typename std::enable_if<
            !std::is_same<typename std::decay<U>::type, Foo>::value>::type>
    Foo(U&&) {

    }
};

int main() {
    Foo<int> ff;
    Foo<char> dd(ff); //here I want a compiler error
    Foo<int> e(15); //it should work
    return 0;
}

我正在尝试添加关于模板构造函数的约束,但是这段代码编译了所以我想我遗漏了一些东西,添加 enable_if 的正确方法是什么?

在您的 main() 函数中,您试图从 Foo<int> 构建 Foo<char>。 decay-based ctor 将 not 在这里工作,因为 Foo<A> 不会衰减到 Foo<B> 即使 A 衰减到 B.请参阅 the cppreference page on std::decay 以详细了解它的作用。

此外,我建议避免使用 pre-decay 类型的显式(模板化)构造函数。如果您的论点也是复制或移动构造函数之一(分别来自 const Foo&Foo&&)衰减为 Foo,那么这些构造函数应该足够了。如果他们不知何故不是,那么您允许的这种隐式转换可能比它的价值更麻烦。它肯定会使您的 class 更难阅读和适应。事实上,您已经看到它导致了一个小错误 :-P

除了打字错误,您还可以利用删除的函数声明,如下所示:

#include <iostream>
#include <type_traits>
template<class T>
class Foo {
public:
    Foo() = default;
    Foo(const Foo&) = default;
    Foo(Foo&&) = default;
    Foo& operator=(Foo&&) = default;
    Foo& operator=(const Foo&) = default;

    
    template<typename K, typename = typename std::enable_if_t<!std::is_same_v<T, K>>>
    Foo (Foo<K> const&) = delete;
    
  
};

int main() {
    Foo<int> ff;
    Foo<int> gg(ff); //THIS WORKS
    //Foo<char> dd(ff); //THIS PRODUCES ERROR
    
    return 0;
}

Demo