Emb*_*eer 8 c++ templates c++14
我有以下代码:
#include <iostream>
#include <string>
#include <type_traits>
struct Foo
{
int i;
int j;
};
template<typename T, T DEFAULT>
class Bar
{
public:
Bar(): mVal(DEFAULT)
{
std::cout << "Bar constructor with mVal = " << mVal << "\n";
}
~Bar(){}
Bar(const T &i) : mVal(i)
{
std::cout << "Bar constructor with mVal = " << mVal << "\n";
}
Bar &operator=(T const &val)
{
mVal = val;
std::cout << "Bar assignment operator with mVal = " << mVal << "\n";
return *this;
}
explicit operator T() const
{
return mVal;
}
private:
T mVal;
};
int main()
{
std::cout << "Hello \n";
Bar<int, 10> bar1;
}
Run Code Online (Sandbox Code Playgroud)
只要第一个模板参数Bar
是整数类型,这在 gcc C++14 中就可以正常工作。如果我想做Bar<Foo, {}>
下面的错误信息打印:
on-type template parameters of class type only available with '-std=c++2a' or '-std=gnu++2a'
Run Code Online (Sandbox Code Playgroud)
我已经预料到了。更改template<typename T, T DEFAULT> class Bar
为template<typename T, T DEFAULT = {}> class Bar
导致相同的错误。template<typename T> class Bar<T, {}>
出于同样的原因,模板专业化也不起作用。
我也尝试过,std::enable_if_t<std::is_integral<T>::value>
但找不到可行的解决方案。
是否有任何可能的方式来只写Bar<Foo>
,而不必像写一个单独的类template<typename T, T DEFAULT> class BarDefault
,并template<typename T> class Bar
为它?
非类型模板参数必须具有结构类型,它是以下类型之一(可选 cv 限定,限定符被忽略):
因此,从 c++20 开始,基本上可以使用自定义结构作为模板值参数。
您可以通过提供依赖于哪个作业提供默认值的模板来解决此问题:
#include <iostream>
#include <string>
#include <type_traits>
struct Foo
{
int i = 42;
int j = 4;
};
std::ostream& operator<<(std::ostream& out, const Foo& a)
{
return out << a.i << ',' << a.j;
}
template<typename T>
struct BarDefaultValue
{
constexpr static T value()
{
return T{};
}
};
template<>
struct BarDefaultValue<int>
{
constexpr static int value()
{
return 42;
}
};
template<typename T, typename D = BarDefaultValue<T>>
class Bar
{
public:
Bar(): mVal(D::value())
{
std::cout << "Bar constructor with mVal = " << mVal << "\n";
}
~Bar(){}
Bar(const T &i) : mVal(i)
{
std::cout << "Bar constructor with mVal = " << mVal << "\n";
}
Bar &operator=(T const &val)
{
mVal = val;
std::cout << "Bar assignment operator with mVal = " << mVal << "\n";
return *this;
}
explicit operator T() const
{
return mVal;
}
private:
T mVal;
};
int main()
{
std::cout << "Hello \n";
Bar<int> bar1;
Bar<Foo> bar2;
}
Run Code Online (Sandbox Code Playgroud)
您可以设置一个默认值来提供。
template<class T>
constexpr T brace_init_value{};
Run Code Online (Sandbox Code Playgroud)
然后用作:
template<typename T, T DEFAULT = brace_init_value<T> >
class Bar
{
Run Code Online (Sandbox Code Playgroud)