下面的代碼如何僅在沒有其他轉換可用的情況下啓用構造函數模板?
#include <iostream>
#include <type_traits>
template <typename T>
struct bar {
bar(const bar<T>&) {
std::cout << "copy ctor\n";
}
template <typename U,
typename = std::enable_if_t<!std::is_convertible_v<U, bar<T>>>>
bar(U&&) {
std::cout << "ctor template\n";
}
};
struct foo {
operator bar<int>() const {
return bar<int>(1);
}
operator int() const {
return 2;
}
};
int main() {
foo my_foo;
std::cout << "constructor: ";
bar<int> my_bar(my_foo);
std::cout << "static_cast: ";
my_bar = static_cast<bar<int>>(my_foo);
}
constructor: ctor template
static_cast: ctor template
作爲輸出。
但是我希望bar的構造函數模板,即template <typename U> bar::bar(U&&)
僅在U
尚未轉換爲bar<T>
時才能啓用。在foo
的情況下,這種轉換已經在foo::operator bar<int>() const
中給出。假設我是bar
的作者,並且對foo
或可能的類似類沒有任何瞭解(或影響)。我怎樣才能說服編譯器在這種情況下使用轉換操作符而不需要完全刪除bar
的ctor模板?
如果構造函數的數量相對較少,請使用這些構造函數定義一個輔助類,然後使用庫存SFINAE方法來查看是否可以構建輔助類。 –
@SamVarshavchik謝謝,這是一個非常好的主意。但在我的情況下,我可以控制和更改'bar',但對'foo'和類似的類沒有任何知識或影響力。我只是把這個假設加到我的問題上。 –
在第二種情況下,使用'static_cast',''ctor模板「'由'bar(1)'打印。似乎按預期工作。 –