在下面的示例中(可以使用 GCC 正常编译),我需要确保非静态成员
value1
和 value2
具有唯一的类型,并且一旦包含 struct Foo
的标头包含在多个 TU 中,它应该' t 导致 ODR 违规。我在链接阶段的项目中遇到了 ODR 错误,因为我在头文件中使用了 decltype( []{} )
,这意味着包含它的每个 TU 都将拥有自己唯一类型的 lambda。
因此我在这里使用
inline static
内部struct Foo
来尝试解决这个问题。
最小的例子:
#include <type_traits>
// Util.hpp
template <typename UniqueType = decltype( []{} )>
inline constexpr UniqueType uniquely_typed_variable { UniqueType { } };
// Foo.hpp
struct Foo
{
inline static constexpr auto unused_var1 { uniquely_typed_variable<> };
inline static constexpr auto unused_var2 { uniquely_typed_variable<> };
using MyType1 = decltype( unused_var1 );
using MyType2 = decltype( unused_var2 );
static_assert( not std::is_same_v<MyType1, MyType2> );
MyType1 value1;
MyType2 value2;
};
// A few .cpp files using "Foo.hpp"
// #include "Foo.hpp"
int main( )
{
[[ maybe_unused ]] Foo foo {};
}
以上是正确的做法吗?或者是否有更优雅的方式来实现这种行为?
解决方案:
#include <tuple>
#include <type_traits>
struct Foo
{
inline static constexpr std::tuple uniquely_typed_values { []{}, []{} };
using MyType1 = std::remove_reference_t<decltype( std::get<0>( uniquely_typed_values ) )>;
using MyType2 = std::remove_reference_t<decltype( std::get<1>( uniquely_typed_values ) )>;
static_assert( not std::is_same_v<MyType1, MyType2> );
MyType1 value1;
MyType2 value2;
};
int main( )
{
[[ maybe_unused ]] Foo foo {};
}